[ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
garethadams
Posts: 8
Joined: Tue Sep 15, 2009 4:09 am

[ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post by qw »

My code is essentially the same as Adam's, except that I chose segment 0000H.
garethadams
Posts: 8
Joined: Tue Sep 15, 2009 4:09 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
User avatar
Andr3w
Member
Member
Posts: 76
Joined: Tue Jun 09, 2009 4:09 am
Location: Somewhere

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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".
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
Last edited by qw on Wed Sep 16, 2009 2:37 am, edited 1 time in total.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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.
Last edited by qw on Wed Sep 16, 2009 2:47 am, edited 1 time in total.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post by qw »

JAL,
Apologies accepted, but I would like to know how you would call them.

Roel
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: [ORG 0x7C00] vs mov ax, 0x07C0 vs jmp 0x07C0:start

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply