flat assembler
Message board for the users of flat assembler.
Index
> Main > jmp treak needed |
Author |
|
vid 25 May 2006, 09:57
i think that variables should be declared in "virtual at" block. That's what virtual is for. org should be 0.
|
|||
25 May 2006, 09:57 |
|
halyavin 26 May 2006, 07:33
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? |
|||
26 May 2006, 07:33 |
|
Tomasz Grysztar 26 May 2006, 09:16
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". |
|||
26 May 2006, 09:16 |
|
halyavin 27 May 2006, 05:41
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 ... |
|||
27 May 2006, 05:41 |
|
Tomasz Grysztar 27 May 2006, 11:30
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 |
|||
27 May 2006, 11:30 |
|
Madis731 29 May 2006, 09:32
Why would
Code: rmptr equ ptr -0x10000 mov eax,data rmptr be worse? Or wouldn't it? |
|||
29 May 2006, 09:32 |
|
halyavin 29 May 2006, 13:41
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. |
|||
29 May 2006, 13:41 |
|
Tomasz Grysztar 29 May 2006, 14:52
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. |
|||
29 May 2006, 14:52 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.