nasm - confusion regarding functionality of ORG directive

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.
shahsunny712
Posts: 20
Joined: Wed Jan 29, 2014 11:57 am

nasm - confusion regarding functionality of ORG directive

Post by shahsunny712 »

I am referring to BrokenThorn's OS development tutorial.

After reading up on stage 2 and beginning to write it on my own, I ran into several doubts regarding the functions of nasm's ORG directive. Here are my questions:

- Is the address given with ORG relative to the current segment (if so, which of CS/DS ?) or to the starting of memory ?
- Does using ORG <address> mean the program will always be loaded at that address ? Is there any guarantee ?
- If in my bootloader I write ORG 0, and assuming its relative to starting of memory, will it replace the code at address 0 ?

Based on your replies I may come up with more questions. This is still a gray area and I want to clear this up before moving to more advanced topics.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: nasm - confusion regarding functionality of ORG directiv

Post by JAAman »

lets take a look at an example:

Code: Select all

start:
MOV AX, 1
MOV BX, 2
MOV CX, 3
JMP NEAR address

;... other things may be here ...

address:
ADD AX, BX
SUB AX, CX
RET

lets suppose that we assemble this code, the assembler needs to know where address is in order to jump to it since the CPU doesn't know anything about labels, the assembler has to turn those labels into addresses


when it assembles this code, it can calculate the offset of where address is relative to the start of the file

thats all fine if the code is located at address 0 in the segment -- it just uses the offset of the data in the file but what if your code is loaded to offset 0x100?
ORG 0x100 tells the assembler that 0x100 should be added to all the labels in the file, because the start of the file will actually be 0x100, thus it applies not to any particular segment selector, but rather to the addresses within the file
shahsunny712
Posts: 20
Joined: Wed Jan 29, 2014 11:57 am

Re: nasm - confusion regarding functionality of ORG directiv

Post by shahsunny712 »

Thank you for your reply.

So here is my understanding:
- ORG address is relative to the starting of the file.
- ORG address is not relative to any segment address.

Remaining questions:
- If ORG is not used, how is the starting address of the file calculated ?
- Is the ORG address added to file's starting address to calculate address of a label, or is there some other addition ?
- Does saying ORG 0x100 replace whatever is at 0x100, assuming file is loaded at that address ?
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: nasm - confusion regarding functionality of ORG directiv

Post by Owen »

All of this assumes the flat binary (-f bin) format. The ORG directive isn't valid for others, so...
shahsunny712 wrote:If ORG is not used, how is the starting address of the file calculated ?
A default is picked (Probably zero)
shahsunny712 wrote:Is the ORG address added to file's starting address to calculate address of a label, or is there some other addition ?
ORG 0x100 says "The next byte in this file starts at address 0x100 in memory". Nothing more complex than that. You can use multiple directives in one file if you want.
shahsunny712 wrote:Does saying ORG 0x100 replace whatever is at 0x100, assuming file is loaded at that address ?
ORG is a hint to the assembler. If has absolutely no effect on the resulting file (other than perhaps changing some address values stored in it)
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: nasm - confusion regarding functionality of ORG directiv

Post by Antti »

At some point is it good to understand what instructions need to know the actual offset. Usually a displacement relative to the next instruction is used and those instructions are position independent. For example, the "JMP NEAR address" above does not rely on the offset so "ORG <address>" does not have any effect on it.

Code: Select all

[ORG 0x0100]

start:
	mov si, string          ; Here "ORG" is important
	call print              ; "ORG" does not matter
	jmp near continue       ; "ORG" does not matter

continue:
	mov ax, quit            ; Here...
	jmp ax                  ; ..."ORG" is important

print:
	mov al, [si]            ; Here "ORG" was important
	<code>
	ret

quit:
	<code>

string:
	db 'Hello World', 0x0D, 0x0A, 0x00
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: nasm - confusion regarding functionality of ORG directiv

Post by JAAman »

Antti wrote:"JMP NEAR address" above does not rely on the offset so "ORG <address>" does not have any effect on it.
WHAT?!?!??!?!?!? since when???? does this mean the rules have changed and none of my code will assemble in new versions of nasm????

because it always used to...


or are you confusing JMP NEAR (uses 16-bit/32-bit/64-bit absolute within segment address) with JMP SHORT (which uses 8-bit/16-bit/32-bit offset from current address, and thus doesn't need to know the actual address)?


edit: taking a closer look at the code you used, the latter seems much more likely... sorry, I initially thought you meant org doesn't apply to branching instructions

in which case however, your code is wrong -- while it often defaults to NEAR, JMP <label> gives the assembler the freedom to use whichever encoding it feels best (which is why i specifically used JMP NEAR rather than assuming the default would be NEAR), while JMP NEAR will force it to always use NEAR (absolute address), and JMP SHORT will force it to use SHORT (offset from current location)
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: nasm - confusion regarding functionality of ORG directiv

Post by Antti »

Since 1978, perhaps. I think it is only assembler syntax that makes sense. I am not confusing anything with ModR/M versions of jumps that you are referring to. In fact, I demonstrated how to use that in the code snippet above.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: nasm - confusion regarding functionality of ORG directiv

Post by Antti »

You still misunderstood. My code is not wrong.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: nasm - confusion regarding functionality of ORG directiv

Post by JAAman »

Antti wrote:Since 1978, perhaps. I think it is only assembler syntax that makes sense. I am not confusing anything with ModR/M versions of jumps that you are referring to. In fact, I demonstrated how to use that in the code snippet above.
and your comments in your code snippet are wrong...


there are 3 forms of JMP:
JMP FAR -- changes segment, requires absolute segment:offset pair
JMP NEAR -- requires 16-bit/32-bit/64-bit absolute address within segment
JMP SHORT -- requires 8-bit/16-bit/32-bit offset from current address

any and all use of JMP NEAR will cause the assembler to emit code using absolute address within segment (and NOT relative addressing)

your example would likely be correct (since NEAR is usually default) if you changed the NEAR keyword to SHORT


and yes, i did just look it up in the nasm manual -- unfortunately it looks like they no longer have a per-instruction descriptions, but the list of instructions was pretty clear, since they list a 64-bit NEAR, but no 64-bit SHORT:
nasm manual wrote: JMP imm|short 8086
JMP imm 8086,ND
JMP imm 8086,BND
JMP imm|near 8086,ND,BND
JMP imm|far 8086,ND,NOLONG
JMP imm16 8086,NOLONG,BND
JMP imm16|near 8086,ND,NOLONG,BND
JMP imm16|far 8086,ND,NOLONG
JMP imm32 386,NOLONG,BND
JMP imm32|near 386,ND,NOLONG,BND
JMP imm32|far 386,ND,NOLONG
JMP imm64 X64,BND
JMP imm64|near X64,ND,BND
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: nasm - confusion regarding functionality of ORG directiv

Post by Antti »

My code and comments are correct. You can give the absolute address within segment if you use an indirect address. I demonstrated it in the code snippet above ("jmp ax"). You could also store the absolute address in a memory location but that would be far from practical in this case.

You can not do "jmp near <absolute address given here as an immediate value>".
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: nasm - confusion regarding functionality of ORG directiv

Post by JAAman »

idk anymore... everywhere I'm looking it doesn't say what i remembered it saying... (although it has been at least 5 years since i looked at it...) I may have been confusing 2 different architectures in my memory

looks like your probably right
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: nasm - confusion regarding functionality of ORG directiv

Post by qw »

Owen wrote:A default is picked (Probably zero)
Indeed, the default is zero.
Owen wrote:ORG 0x100 says "The next byte in this file starts at address 0x100 in memory". Nothing more complex than that. You can use multiple directives in one file if you want.
With MASM you can. With NASM you can't:
The [url=http://www.nasm.us/xdoc/2.11/html/nasmdoc7.html#section-7.1.1]NASM Manual[/url] wrote:Unlike the ORG directive provided by MASM-compatible assemblers, which allows you to jump around in the object file and overwrite code you have already generated, NASM's ORG does exactly what the directive says: origin. Its sole function is to specify one offset which is added to all internal address references within the section; it does not permit any of the trickery that MASM's version does.
JAAman wrote:looks like your probably right
He is: http://read.seas.harvard.edu/cs261/hwref/i386/JMP.htm, opcode E9.
shahsunny712
Posts: 20
Joined: Wed Jan 29, 2014 11:57 am

Re: nasm - confusion regarding functionality of ORG directiv

Post by shahsunny712 »

Okay, so here's what I gather:

While assembling, the file is assumed to have a starting address of 0x0.
Now an instruction ORG 0x100 is encountered. Thus, all labels have their addresses added by 0x100 within the file.
Assuming the file is finally loaded at say 0x500 in memory, the labels would further get added by 0x500 (by the loader perhaps ?). This address where the file is loaded may be same as ORG, but not necessarily and OS takes care to not replace any existing code.

Please correct me if I am wrong.
Also, for JMP NEAR, we need an absolute address within the segment. This is not available to the assembler, and the final absolute address would be determined by the loader. Is that right ?

(Please note that I am thinking of this as having two distinct stages - the assembly part by the assembler and the loading in memory by the loader).
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: nasm - confusion regarding functionality of ORG directiv

Post by qw »

The origin is the base address of the binary. If it is to be loaded at 0x0500 then you must supply ORG 0x0500. Supplying ORG 0x0100 would be silly.

There is no relocation information in the binary format so a loader cannot fix up addresses. Addresses are hard-coded by NASM. The ORG directive is necessary for those addresses to be correct. This explains why the binary format has an ORG directive in the first place. The other formats use a linker to calculate the correct addresses.

Short and near jumps with an immediate displacement are relative, which means that the displacement is added to the instruction pointer. Short jumps have an 8-bits displacement which is sign-extended before addition.
EB 00 and E9 0000 are effectively no-ops: they add zero to the instruction pointer, which causes the following instruction to be executed (because the instruction pointer is already pointing to the following instruction).

Note that we're only talking about offsets here, not segment addresses.
shahsunny712
Posts: 20
Joined: Wed Jan 29, 2014 11:57 am

Re: nasm - confusion regarding functionality of ORG directiv

Post by shahsunny712 »

The functionality is now clear to me, thanks.

Just one question now:
Let's say I compile my .asm file and generate a .bin file. I have given ORG 0x500 in my asm.
How is this value stored in the .bin to indicate that 0x500 should be used for the starting address ? I'm not aware of any instruction for this.

If it is indeed stored, what if that location is not available when the .bin is executed ?
If it's not stored, how is the value used ?

It's possible I'm missing something fundamental here, but I'm not being able to catch that.
Post Reply