ORG and .org and 0x7c0

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.
Post Reply
jinksys

ORG and .org and 0x7c0

Post by jinksys »

I know that the bios loads my code into the memory address
0000:7c00, but how does this affect my code?

I see boot sectors (mainly in intel/nasm syntax) that all have
org 0x7c0 as their first statement, yet all of my bootsectors ( I hate
calling them that because they dont actually load anything) work
fine and dont have that preceding the code.

Could someone explains this to me, Im not getting the point...or maybe its too early in the morning....
Curufir

Re:ORG and .org and 0x7c0

Post by Curufir »

Ok, to clear up one thing, you'll be seeing ORG 0x7C00 not ORG 0x7C0 (Unless they're twisted freaks).

The ORG statement basically tells the compiler to add 0x7C00 to every label before assembling.

In real mode you have a segment:offset style of addressing.

Physical address = segment * 16 + offset.

So far so good.

Therefore 0x7c00 can be represented in at least 2 ways.

0x7c0:0x0 = 0x7c00
0x0:0x7c00 = 0x7c00

Now the first way all you have to do is load the segment (DS/CS etc) with 0x7c0, and labels can be used as though the program was loaded at 0x0 (ORG 0x0, which is default when no ORG statement is present).

The second way you have to adjust all the labels by 0x7c00 to make them correct. Hence the reason for the ORG statement.

There's little difference between the two, but the second is probably more common among people uncomfortable with segment:offset addressing.

Oh, and a fun gotcha. There is no standard that dictates which form the BIOS should use for CS:IP when jumping to 0x7c00. So don't rely CS/IP being known in your bootsector unless you set them yourself (Far jump will do the trick).

HTH

***

Thought I'd add a quick note. This stuff mainly applies to data references, which are pointers. Under general circumstances code references (Eg JMP, CALL etc) are all done as relative offsets, so they independent of load address.
jinksys

Re:ORG and .org and 0x7c0

Post by jinksys »

Under general circumstances code references (Eg JMP, CALL etc) are all done as relative offsets, so they independent of load address.
oooh! I was wondering why data references didnt work unless I set DS to
0x7c00, yet jumps did.
Ok, to clear up one thing, you'll be seeing ORG 0x7C00 not ORG 0x7C0 (Unless they're twisted freaks).
Really? Because this is confusing...I get different answers from different
sites. Ive heard that the bios loads you to 07c0:0000 or 0000:7c00,
which is the same linear address if I used (16 * segment * offset)
correct.

But this site says, "If a valid boot sector is found, it is loaded into memory at location 0:07C0h." Segment 0 Offset 07c0?
http://kos.enix.org/pub/bootwrit.html

Is he wrong? Or am I losing it :)

Do you know of a Gas equivalent expression for ORG 0x7C00 that does
not fill the image with 0's instead of manually adding offsets to references?




Thanks!
Curufir

Re:ORG and .org and 0x7c0

Post by Curufir »

I tried to cover this, maybe I was too cryptic :).
Curufir wrote: Oh, and a fun gotcha. There is no standard that dictates which form the BIOS should use for CS:IP when jumping to 0x7c00. So don't rely CS/IP being known in your bootsector unless you set them yourself (Far jump will do the trick).
He's wrong. Assume nothing about CS/IP at bootsector entry other than the fact that together they make a physical address of 0x7c00.

In fact I'd go farther and say that you should assume absolutely nothing aside from:

a) Your code will be loaded to a physical address of 0x7c00
b) The disk drive id will be loaded in DL.

Assume everything else is just worthless and setup a good, known, environment as soon as is humanly possible.

***

From that link

Code: Select all

        mov ax,0x7c0    ; BIOS puts us at 0:07C0h, so set DS accordinly
        mov ds,ax       ; Therefore, we don't have to add 07C0h to all our data
He has got confused over real-mode addressing. Luckily, since he loads 0x7c0 into DS, that confusion doesn't stop his code working. Dig up Perica's real-mode addressing article at http://www.osdever.net/ if you're still confused about this form of address.

***

GAS has the ORG statement, although probably (Like everything else) not in a familiar form for anyone from MASM/NASM/FASM. It's a general assembler type thing (Haven't seen one without it).
jinksys

Re:ORG and .org and 0x7c0

Post by jinksys »

Thanks for the excellent explanations!
Slasher

Re:ORG and .org and 0x7c0

Post by Slasher »

The Best way to setup DS to point to the same segment as CS (where the bios loaded your boot code) is

push cs
pop ds

this way even if CS is 0x0 or is 0x07c0 (some BIOS load cs with 0 while others load Cd with 0x07c0) your code will work
Curufir

Re:ORG and .org and 0x7c0

Post by Curufir »

No, that's a terrible way to do things.

If CS = 0x0 then you would be relying on an ORG 0x7c00
If CS = 0x7C0 then you would be relying on an ORG 0x0

In either case you would be relying on guess correctly the value of something that can only really be determined at boot time.

Set the segments up manually with values that compliment your ORG setting, by explicitly loading DS/ES, and performing a far jump to set CS.
Cemre

Re:ORG and .org and 0x7c0

Post by Cemre »

if i were you, i would make the
bootsector program start like the following...

i SAW some compaq bioses start from 0x0000:0x7C00,
though normally it should start from 0x07C0:0x0000
org 0x7C00
jmp 0x0000:Start
Start:

; rest of the code
Cemre

Re:ORG and .org and 0x7c0

Post by Cemre »

well of course if you set up all the segment
registers, it would be better
Start:
cli
mov ax,cs      ; Load CS DS ES SS
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0xFFF8      ; Load IP SI DI SP BP
xor bp,bp
sti
Schol-R-LEA

Re:ORG and .org and 0x7c0

Post by Schol-R-LEA »

The general solution (as Cemre showed but did not explain) is to do a JMP FAR at the beginning of the code, to a label marking the actual start of the code, aligned to the appropriate segment base. This will ensure that the segment and offset match those in your code. For example:

Code: Select all

[org 7c00]

entry: jmp 0000:start

start: ...
will ensure that CS is set to 0000 and IP is set to [tt]start:[/tt].
asmboozer

Re:ORG and .org and 0x7c0

Post by asmboozer »

bits 16
org 0

   jmp 07c0h:start

start:
   push cs
   pop ds
   
   mov ax,ds
   mov es, ax


this works too, the two forms of org/jump usage may help u understand it
Post Reply