Page 1 of 3
[ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 4:52 am
by garethadams
Hi,
Sorry if this is a really stupid question but I've tried reading many different tutorials and couldn't find a specific answer.
Some tutorials do this:
Code: Select all
[ORG 0]
jmp 07C0h:start ; Goto segment 07C0
start:
; Update the segment registers
mov ax, cs
mov ds, ax
mov es, ax
Others do this:
Code: Select all
[BITS 16] ; 16 bit code generation
[ORG 0x7C00] ; Origin of the program. (Start position)
; Main program
main: ; Put a label defining the start of the main program
Others do this:
Code: Select all
mov ax, 0x07C0 ; set up segments
mov ds, ax
mov es, ax
Is it just personal preference or are there situations when you'd use one over the other?
Thanks
Gareth
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 5:12 am
by qw
The BIOS loads the boot block at physical address 07C00H but there is no guarantee that it is logical address 0000:7C00H or 07C0:0000H. To set all segment registers to 0, this should do:
Code: Select all
[org 7C00H]
jmp 0:start
start:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, ...
I prefer this because it gives you direct access to the Interrupt Vector Table and the BIOS Data Area.
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 5:13 am
by AJ
Hi,
They are all doing different things - version 1 sets code and data segs, version 2 assumes segment values and version 3 only assumes the code seg value, but sets the data segs.
Version 1 is the most correct. Do not assume that any of the segments are set to 'nice' values to start with. This means that you should start with:
Code: Select all
[BITS 16]
[ORG 0]
jmp 0x7C0:main
main:
mov ax, 0x7C0
mov ds, ax
mov es, ax
mov ss, ax
mov sp, [whatever you like]
Of course, if you prefer to run at 0x0000:0x7C00 or 0x0001:0x7BF0 or whatever else, you are very welcome to!
Cheers,
Adam
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 5:44 am
by qw
My code is essentially the same as Adam's, except that I chose segment 0000H.
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 6:09 am
by garethadams
Cool, thanks guys! I wish tutorial writers would explain any assumptions they make, especially when doing such a basic "hello world" tutorial. Then again, it's probably just me that needs to know what every bit of code does and why - I'm sure others are happy just to accept "that's just how it is"!!
I'm sure I'll be back with more questions.
Gareth
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 6:59 am
by jal
AJ wrote:Code: Select all
[BITS 16]
[ORG 0]
jmp 0x7C0:main
main:
mov ax, 0x7C0
mov ds, ax
mov es, ax
mov ss, ax
mov sp, [whatever you like]
It's been a while since I dabbled with real mode assembly, but iirc, the ORG statement is mainly there for the values of the labels, right? So "main" is offset to whatever ORG says. Since the BIOS loads the boot sector at 0x7c0, the jmp uses that as segment. The fact that there is even a jmp is mainly because most(?) people like to put their data above the main? In this particular code, the jmp seems rather superfluous.
JAL
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 7:00 am
by jal
Hobbes wrote:The BIOS loads the boot block at physical address 07C00H but there is no guarantee that it is logical address 0000:7C00H or 07C0:0000H.
That's just nonsense. There is no "physical" or "logical" address in real mode. I think you know what you mean, but that's not what you describe here...
JAL
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 7:07 am
by Andr3w
jal wrote:Hobbes wrote:The BIOS loads the boot block at physical address 07C00H but there is no guarantee that it is logical address 0000:7C00H or 07C0:0000H.
That's just nonsense. There is no "physical" or "logical" address in real mode. I think you know what you mean, but that's not what you describe here...
I think he wanted to say that some BIOSes load your bootsector to
0000:7C00h and some load to
7C00h:0000..
Am I right?
-- Andrew
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Tue Sep 15, 2009 7:13 am
by JamesM
jal wrote:Hobbes wrote:The BIOS loads the boot block at physical address 07C00H but there is no guarantee that it is logical address 0000:7C00H or 07C0:0000H.
That's just nonsense. There is no "physical" or "logical" address in real mode. I think you know what you mean, but that's not what you describe here...
JAL
There is a logical address in real mode. The logical address is equal to "(segment << 4) + offset". There are multiple ways of obtaining the same logical address from segment:offset pairs, and the OP is stating that the BIOS does not define what the initial state is. Is the code segment 0000h and the IP 7c00h? or is the code segment 07c0h and the IP 0000h.
You're not stupid, it's obvious what he meant. Even I got it and I know nothing about real mode programming. Your response was incorrect - it is not "nonsense".
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Wed Sep 16, 2009 2:31 am
by qw
JAL,
With logical address I mean segment:offset. The physical address is segment * 16 + offset, which is the value sent over the address bus. 0000:7C00H and 07C0:0000H are two logical addresses to the same physical address.
Roel
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Wed Sep 16, 2009 2:36 am
by qw
jal wrote:It's been a while since I dabbled with real mode assembly, but iirc, the ORG statement is mainly there for the values of the labels, right? So "main" is offset to whatever ORG says. Since the BIOS loads the boot sector at 0x7c0, the jmp uses that as segment. The fact that there is even a jmp is mainly because most(?) people like to put their data above the main? In this particular code, the jmp seems rather superfluous.
The BIOS could have loaded the boot block to 0000:7C00H, but the code assumes it's 07C0:0000H. In this case, the assumption is wrong, so the jump is necessary, unless the code uses relative jumps only. The data registers have to be set anyway.
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Wed Sep 16, 2009 5:28 am
by jal
Hobbes wrote:With logical address I mean segment:offset. The physical address is segment * 16 + offset, which is the value sent over the address bus. 0000:7C00H and 07C0:0000H are two logical addresses to the same physical address.
Yeah, I should've thought first, then wrote. In retrospect, I should probably have written "confusing" instead of "nonsense". My sinsere appologies.
JAL
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Wed Sep 16, 2009 5:30 am
by jal
Hobbes wrote:The BIOS could have loaded the boot block to 0000:7C00H, but the code assumes it's 07C0:0000H. In this case, the assumption is wrong, so the jump is necessary, unless the code uses relative jumps only. The data registers have to be set anyway.
Ok, I see, it's just to make sure the CS is whatever you want it to be. Still, the BIOS loads the bootblock to 7c000h (the "pysical address" from your previous post). It's just that the code cannot assume anything about the current value of CS:IP when the code is run. Hence the jmp, to initialize them both. I get it! :) But indeed I was thinking about relative jumps, as the bootblock is 512 bytes anyway, you wouldn't need to many non-relative ones...
JAL
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Wed Sep 16, 2009 12:15 pm
by qw
JAL,
Apologies accepted, but I would like to know how you would call them.
Roel
Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start
Posted: Wed Sep 16, 2009 12:19 pm
by Brendan
Hi,
I just wanted to mention that some old computers don't check if the "0x55 0xAA" magic bytes (at offset 511 and 512 in the first sector) are present; and some old computers (maybe just old Compaqs) check that the first bytes in the sector correspond to a JMP instruction instead.
Also, those "0x55 0xAA" magic bytes really are meant to be at offset 511 and 512 in the first sector (rather than the last 2 bytes of the sector). This might seem like it's exactly the same thing, until you consider (for e.g.) floppy disks that are formatted with 1024-byte sectors or larger sectors (which is something that the BIOS is meant to support, but also something that I'd assume most BIOSs have bugs/problems with).
Cheers,
Brendan