flat assembler
Message board for the users of flat assembler.

Index > OS Construction > org 0x10000 in rmode?

Author
Thread Post new topic Reply to topic
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Hi, I am having some problems that might be fasm related.
I recently decided to let my kernel start in realmode, as i need to save some stuff in order to go back to realmode.
The kernel is loaded to 64kb in memory, so when it was completly 32-bit i used org 0x10000.
Now when adding 16-bit code, the kernel starts in realmode, and then goes to pmode. The problem is that with org 0x10000 i get the fasm error "value out of range" on the line " jmp 0x08:do_pmode" when i try to compile it.

It turns out that the error disapears if i change org to something with 4 digits. So i think that i need to set ut the org acourding to realmode rules, which would be "org 0" with ds, es etc as 0x1000 ? (been a while since my last 16-bit work)
But then what should i do after i enter pmode? Wouldn't the "org 0" casue trubble then?

Any suggestions to this?

/ Christoffer

_________________
BOS homepage: http://bos.asmhackers.net/
Post 26 Mar 2005, 20:58
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
Hi Bubach,

If your code is 16-bit I don't beleive that and 'ORG 0x10000' is useable, since the register for the IP is only 16-bits. Thus an address of 0xffff is the maximum value unless you can increment the CS. So yes, to answer your question your DS, ES, and CS would be, from your example, 0x1000.

I'm trying to get a handle on what you're trying to do. If I understand you correctly, the begining of your code is 16-bit(?). The rest of your code is 32-bit(?). A possible solution, since you're loading directly from floppy (I assume) into the startup state and relocating your code to 0x10000 is to seperate the 16-bit and 32-bit parts and compile them seperately. Then combine them afterwards with the copy filename.ext/b + filename2.ext/b combinedfilename.ext. While this seperates your code, it allows you the ability to seperate the two parts. You could use your ORGs according to the convention you're within. In doing this, it is best to establish a known endpoint for your 16-bit code though (much like boot sectors) and your far jump would be from the 16-bit code to that known address "JMP 0x08:0x20000" if you allowed for 64kB for 16-bit. then your org in 32-bit would be 0x20000, the start of that code.

I hope that helps...
Post 28 Mar 2005, 12:45
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
@smiddy, bubach is trying to go back from pmode to realmode, do a BIOS interrupt and go back to pmode, with out messing his pmode address up.
Post 28 Mar 2005, 17:28
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
Hi Dex4u,

Then it might be worth it to setup certain segments (address specific) within the code and do something similar to what I suggest:

PMODE Code [certain size known location in memory]
RealMode Code [64KB with a CS pointing to the start of this code entry]
PMODE Code [unlimited size]

Then compile each part seperately as described above and do the same thing. The issue is the dynamics of the memory locations for the far jmp, which would be hard coded. So update the gdt with the 16-bit code and data segments, do the branch: jmp 0x1000:0000 (using ORG 0x0 for the 16-bit code), then hard code a return after reapplying the GDT with the 32-bit info: jmp 0x08:PMODE_CODE (or the specific address).

I have experimented with this breifly and don't have the information here at work. If I remember I'll send Bubach my code tonight (y'alls early morning).
Post 28 Mar 2005, 19:30
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Hi, smiddy,
I am shore your code with help, i have code for switch back to realmode in "Dex4u" which works find in "Dex4u" , but not in BOS (bubachs OS), a old ver of my code is in this topic: http://board.flatassembler.net/topic.php?t=1854
Post 29 Mar 2005, 02:37
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Fixed it... Thanks for the help.
Attached solution in both nasm and fasm syntax, by gaf.

/ Christoffer


Description: A solution to my problem. PM1 is some example code made for me by gaf, from the http://osdcom.info/ messageboard.
Download
Filename: pm1_by_gaf.zip
Filesize: 4.55 KB
Downloaded: 245 Time(s)


_________________
BOS homepage: http://bos.asmhackers.net/
Post 29 Mar 2005, 06:45
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Hi!

Sorry to bump such an old topic, but I just minutes ago tried the new fasm 1.70 (used 1.60 from 2005 until now) and this "problem" just got much worse.

With the old fix from gaf, I had to subtract 0x10000 which is the kernel org value for 32-bit, from all variable refrences while in 16-bit mode. Nasm happily ignored the org value while in realmode.

See the attachment in my previous post from 2005 for an example on how this looks in fasm vs. nasm.


But now with this update to the newest fasm version, i also have to do "jmp label-0x10000" instead of "jmp label", so it now affects jumps and calls too! I'm not sure why, and how this can be a desirable result? Is there no other way, my 16-bit code inside the kernel looks like shit with all these "fixes"... Sad

Can I use a different org value (0x0000) on the 16-bit parts, and still have org 0x10000 while in pmode? Or does anyone have a cleaner solution?

Regards,
Christoffer
Post 17 Apr 2012, 22:46
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
bubach wrote:
But now with this update to the newest fasm version, i also have to do "jmp label-0x10000" instead of "jmp label", so it now affects jumps and calls too! I'm not sure why, and how this can be a desirable result? Is there no other way, my 16-bit code inside the kernel looks like shit with all these "fixes"... Sad
The jumps have been corrected some time ago (around 1.66, I think) and since then when you have 16-bit code, the default address size for jump is word (and so it generates instruction that affects IP and zeroes the high bits of EIP). Of course in such case it is impossible to do "jmp 0x10000", because it would really be "jmp 0" after the address being truncated down to IP. If you really wanted to jump to 0x10000 address, you would have to use "jmp dword 0x10000" to tell fasm that you want to have prefixed jump instruction that uses EIP instead of IP.

But in your case it is different - I see that you want to have different addresses for the kernel depending on whether you are in 16-bit or protected mode. There are a few possible solution to this, depending on your exact usage scenario.

I suspect that when you jump from 16-bit code, you jump to the address that also is in 16-bit code (not counting the mode switch). In such case it should be enough to redefine ORG for each piece of code:
Code:
org 0
use16
; initial 16-bit code at address 0
org 0x10000+$
use32
; some 32-bit code, addresses relative to 0x10000 base
org $-0x10000
use16
; again some 16-bit code addressed relative to 0
org 0x10000+$ 
use32 
; again 32-bit code, etc.    
This doesn't solve the problem, when you want to address the same data from both modes, that is: use two different addresses for the same label. Then you have to adjust the address manually, or make some macros that might ease things a bit.
Post 17 Apr 2012, 23:01
View user's profile Send private message Visit poster's website Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Yeah, thats the problem.. I not only collect data about RAM and such in 16-bit, but I also support going back and forth to realmode for BIOS calls -involving saving/reading the same variables in both modes.

I'll have to experiment some with setting the org value as you described - because this is a real bummer. Even if the 16-bit code is rather static and not changed often, it doesn't look very nice.

For now I changed back to 1.60 but maybe I have to live with the fact of subtracting 0x10000 from everything.

What does this kind of behavior affect, I mean how come it works fine with both variables and jumps in nasm? nasm seems to completly ignore the org statement while in 16-bit mode..
Post 17 Apr 2012, 23:13
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
bubach wrote:
What does this kind of behavior affect, I mean how come it works fine with both variables and jumps in nasm? nasm seems to completly ignore the org statement while in 16-bit mode..
Maybe it truncates the addresses? Doing something like "and 0FFFFh"?

This is in fact what old fasm did (incorrectly) when you did "jmp label" from 16-bit code at org 10000h, it did generate instruction that would truncate address down to IP, so if label=1004Fh, it would jump to 004Fh instead of 1004Fh. When I found this out, I realized it was a bug (at least from the point of view of fasm's design) and so I made fasm check whether the value would get truncated and signalize an error in such case.
Post 17 Apr 2012, 23:25
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
bubach, my solution to this was to create a GDT with descriptors for real, unreal, and protected modes. I am careful about labeling, and have made mode specific functions. I only use INT 10h from real mode (which also means using two separate IVTs as well). I leave the real mode code below the 65k boundary, and everything else is above it, using a DOS MZ EXE. My offset is based on how the CS gets loaded, since I can run it from DOS directly or via a boot loader. I use an origin of 0h, loading the CS value to the rest of the segments on start up. Then I don't have to label math to get to functions. If you wish I can send you my source so you can take a look and see what I mean specifically.
Post 18 Apr 2012, 21:26
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
Hmm, being able to run from DOS seems like a good idea, but I'm not sure if the MZ-format doesn't complicate things.

I too have GDT entries for both PM and RM, but not unreal mode. And I keep the real mode interrupt vector table so that when I do a BIOS interrupt, my own 32-bit int, starts by saving down the ax-dx values into variables, goes to real mode, resets the IVT and does the BIOS call before restoring everything and going back to protected mode.

If i understand you correctly, you do not use a 0 based GDT entry for your 32-bit code? So the offset (org) can always be zero both in RM and PM? Maybe i could use something like that in my kernel too, and just have extra GDT entries for loadable (relocatable) drivers/programs that are truly 0-based flat segments.

Possibly I could just move my kernel down a few kilobytes below 64kb and make sure that all 16-bit code is under the limit. Having the ORG value valid for both 16 and 32 bit that would probably make things easier for me. but a fixed loading address might also make it hard to make a freestanding dos loader?

anyway I'll have to investigate different approaches to this later, but for now i'm all in on getting my FAT12 code working - almost done with read support now anyway (all code written) just have to debug it to work, been tracing calls in bochs dgb for hours already.. Sad

Feel free to post a link to your source as a PM or something, it might give me ideas - otherwise I can get back to you when I actually start doing something about this situation (won't be right away). Razz
Post 18 Apr 2012, 22:08
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
No hurry, then. I will PM you a link. It may be fun to look at my "other" oddities. LOL
Post 19 Apr 2012, 00:24
View user's profile Send private message Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach
hehe, yeah i'm a bit curious what you have gotten done since i last had a look Smile
Post 19 Apr 2012, 01:02
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
Nothing really...LOL I'm currently working on 64 bit memory manager, which is taking me FOREVER since I get 15 to 30 minutes every other day to play with it.
Post 19 Apr 2012, 02:24
View user's profile Send private message Reply with quote
egos



Joined: 10 Feb 2009
Posts: 144
egos
bubach wrote:
Yeah, thats the problem.. I not only collect data about RAM and such in 16-bit, but I also support going back and forth to realmode for BIOS calls -involving saving/reading the same variables in both modes.
If you will use image base <0x10000 (e.g. 0x8000) you will can use same linear address space for 16-bit and 32-bit code:
Code:
org 8000h
; use16
...
mov al,[a]
...
a db ?

virtual
rb 10000h-$
end virtual

use32
...
mov al,[a]
...
    

_________________
If you have seen bad English in my words, tell me what's wrong, please.
Post 19 Apr 2012, 09:49
View user's profile Send private message 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 GitHub, YouTube, Twitter.

Website powered by rwasa.