flat assembler
Message board for the users of flat assembler.

Index > Main > jmp treak needed

Author
Thread Post new topic Reply to topic
halyavin



Joined: 21 Aug 2004
Posts: 42
halyavin
MenuetOS sources can't be compiled with fasm 1.66 Sad . The problem is in jmp syntax. Start up code of MenuetOS begin with org 0x10000 in order to correctly generate addresses of variables (for using in protected mode). But code really executed by org 0x0 because cs=0x1000. Fasm doesn't know about that and gives error for all jmp and call instructions because current address exceeds 0x10000. How work around this errors?
Post 25 May 2006, 08:39
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
i think that variables should be declared in "virtual at" block. That's what virtual is for. org should be 0.
Post 25 May 2006, 09:57
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
halyavin



Joined: 21 Aug 2004
Posts: 42
halyavin
BTW, If I write jmp address%0x10000 it works - fasm checks bounds only for destination. But it requires writing macroses for all conditional commands (and then purging them in protected mode). If there is no more simple way I will use this.

Using org 0x0 ruin all data and code in protected mode part of kernel (which use flat model). Also data in real mode aren't located in one place - so many virtual directives will be needed.

Others assemblers seems to solve this problem using "assume" directive.

PS What means "jmp dword label_name" in 16-bit mode?
Post 26 May 2006, 07:33
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7750
Location: Kraków, Poland
Tomasz Grysztar
If the data is present in the source file aswell as code, but they are loaded into different addresses, you should use ORG twice, once for every part of the file that will get loaded into some other place.
If the file contains only the code with ORG 0, and the data is at some different address, but not loaded from source file (and thus uninitialized), you have to use VIRTUAL, as vid said.
When writing a kernel, though, it's usual to need a multiple ORG directives (same as with NASM - I don't know however, what other assemblers you used previously). But also VIRTUAL directive was initially specially designed to aid the kernel programming (see some notes on fasm's history in Design Principles).

PS. "jmp dword" in 16-bit mode is the same as "jmp far dword", this is 16:16 far jump. The 16:32 far jump is done with "jmp far pword".
Post 26 May 2006, 09:16
View user's profile Send private message Visit poster's website Reply with quote
halyavin



Joined: 21 Aug 2004
Posts: 42
halyavin
Current code (which can be successfully compiled by both FASM 1.64 and 1.66) looks like this:
Code:
use16
org 0x0 ;cs=0x1000
;  some real-mode code
org $+0x10000
; some initialized data, which is used in protected and real mode
org $-0x10000
; some real-mode code
org $+0x10000
; some initialized data, which is used in protected and real mode
org $-0x10000
;some real-mode code
jmp $+2
org $+0x10000 ;now we in protected mode
;some protected-mode code which doesn't use variables
use32
;some protected-mode code
use16
shutdown:
org $-0x10000
;some shutdown code (cs=0x1000 here)
org $+0x10000
; some data, which is used in protected and real mode
org $-0x10000
use32
org $+0x10000
;rest of protected-mode code
;all protected mode initialized data
;all protected mode unitialized data
    


All kernel code is loaded at 0x10000 address, but CS base is not equal zero in real-mode code. There is no unitialized real-mode data, so virtual will not help. (Real-mode code uses commands like mov eax,[data-0x10000] in order to access variables. This have been designed from the beginning.) Also we can't move real-mode data to the end of the file, because kernel size is greater than 64Kb and so offset exceeds 64Kb limit.

Previously we have only org 0x10000 at the start of the OS. Also, load directive will not work between different org blocks. We are lucky that in current kernel, place where load used and source of the load can be put in one org block (we use load in order to automatically copy information about OS name and version to some messages). But this requires writing org $+0x10000 in one file, but writing corresponging org $-0x10000 in another file.

Updating to FASM 1.66 is a big pain for KolibriOS/MenuetOS kernel developers...

PS Code with jmp address%0x10000 can't be compiled in FASM 1.64 ...
Post 27 May 2006, 05:41
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7750
Location: Kraków, Poland
Tomasz Grysztar
The ORG is needed only for absolute addressing, for the code that uses only near (and thus relative jumps) to itself you don't need an ORG at all.
The only problem that rises here is when you want to use two different addressing modes (and so need two different address values) for the same data. Since in fasm label has a fixed address, you'd have go deal with it using some macros. Or just use single ORG 0x10000 and write "-0x10000+" before every addressing that applies to real mode. This can be simplified by making some symbolic constant, like:
Code:
rma equ -0x10000+    

and then use it like:
Code:
mov eax,[rma data]    

Or even:
Code:
rmptr equ ptr -0x10000+
mov eax,rmptr data    
Post 27 May 2006, 11:30
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2140
Location: Estonia
Madis731
Why would
Code:
rmptr equ ptr -0x10000
mov eax,data rmptr
    

be worse?
Or wouldn't it?
Post 29 May 2006, 09:32
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
halyavin



Joined: 21 Aug 2004
Posts: 42
halyavin
Tomasz Grysztar wrote:
The ORG is needed only for absolute addressing, for the code that uses only near (and thus relative jumps) to itself you don't need an ORG at all.

For FASM 1.64 this is true but for FASM 1.66 this is false. Code below can't be compiled:
Code:
use16
org 0x10000
jmp next
next:
    

It gives
Code:
flat assembler  version 1.66
test.asm [3]:
jmp next
error: value out of range.
    
Post 29 May 2006, 13:41
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7750
Location: Kraków, Poland
Tomasz Grysztar
Right, the boundaries checking (and many other things aswell) with jumps has been corrected. You have to either do "jmp dword next" or "jmp next and 0FFFFh", depending on what do you expect. Thus for 16-bit code you perhaps need the right ORG anyway (since, as I guess, it will be executed only in 0-based addressing, otherwise you'd need some tricky U32 code).

Anyway doing so much mixing of code appears strange for me. Why not put all real mode code in one place? But if for some reason you think that this way it's better, you should just make some macros to make the switching easier. Perhaps something like:
Code:
macro use16 
{ 
 use16
 org $ and 0FFFFh 
}
macro use32 
{
 use32
 org $ and 0FFFFh + 10000h
}    

combined with the solution for data addressing I mentioned earlier.
Post 29 May 2006, 14:52
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.