Author Topic: Is there alternative code for the ORG directive?  (Read 21663 times)

David

  • Guest
Is there alternative code for the ORG directive?
« on: February 11, 2010, 05:54:02 PM »
Hello again!

I need to know exactly what the ORG directive does. Could anyone show me an alternative way to do the same thing, only without using it?

Thanks!

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: Is there alternative code for the ORG directive?
« Reply #1 on: February 11, 2010, 06:57:36 PM »
NASM Doc - ORG

The alternative to ORG and flat binaries is to utilize an object format (e.g. ELF) and a corresponding linker such as ld, jloc, etc.

David

  • Guest
Re: Is there alternative code for the ORG directive?
« Reply #2 on: February 11, 2010, 08:05:26 PM »
Thanks Keith Kanios, I already know that though. I am wondering if there is a way to do it in the source code. I assume no? The reason I ask is because if I pass control to another program at a random origin, I need to re-ORG in the original program. NASM won't let me do that. What I mean is I need to set the ORG for the program I am passing control to. Maybe there is no way to do this, I am not sure. Maybe I am on the wrong track altogether.

Thanks,
David
« Last Edit: February 11, 2010, 08:07:21 PM by David »

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: Is there alternative code for the ORG directive?
« Reply #3 on: February 12, 2010, 12:11:37 AM »
You'll want to look into position independent code.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is there alternative code for the ORG directive?
« Reply #4 on: February 13, 2010, 04:41:32 PM »
Sure:

; Nasm defaults to org 0, if we don't say
; org 0

mov dx, msg + 100h
mov ah, 9
int 21h
ret

msg db "no org!$"

"org" just gives Nasm a number to add to the file-offset when calculating the address of variables. It doesn't "cause"  a dos .com file (for example) to be loaded at 100h, it merely informs Nasm that that's where the code *will* be loaded. For code that will be loaded at one address, and moved to another address before being run, Nasm provides a "vstart" property to an arbitrary section, which *might* help you. See the manual for more.

If we don't know where the code will be loaded when it's run - position-independent code, like Keith said. This is mostly easier than it sounds - jmp, jcc, call, etc. are "relative addressing" and don't depend on the actual position of the code - just "distances". Finding variables is a problem - we can't "mov dx, msg", 'cause Nasm doesn't know where "msg" is going to be. We can take advantage of the fact that "call" will put a return address on the stack, whatever it might be...

jmp find_address
got_address:
pop dx  ; pop return address provided by "call"
mov ah, 9
int 21h
ret

find_address:
call got_address
db "found me!$"

If that doesn't help, tell us more about how you're passing control from one program to another...

Best,
Frank


David

  • Guest
Re: Is there alternative code for the ORG directive?
« Reply #5 on: February 18, 2010, 10:46:49 PM »
I do know where the code will be loaded, but it may not always be the same. Say I want to load at 100h at one time and 8000h at another.

Does your way work for this?

Thanks!
David

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is there alternative code for the ORG directive?
« Reply #6 on: February 19, 2010, 12:32:19 AM »
Yeah, you want "position independent code". The alternative, as Keith points out, is a "relocation table", which you would get with a linkable object format. Windows ".dll"s have a "preferred" address, but if it needs to be loaded elsewhere, it has a relocation table, and can be "relocated" to another address (some "fudge factor" is added to all the fixed addresses). Linux shared libraries lack a relocation table, and have to be able to run at any address. From something Keith showed us the other day, Mac compilers apparently generate position independent code by default (dunno why).

But if you're going to load at 100h one time, and 8000h another, how is the "calling" code going to find it? No doubt, you can find a solution to that, but by the time you're done, you'll have reinvented the linkable file format. Maybe you'll come up with a better one!

If you've got multiple variables, the "call and pop the address" trick will get tedious. I'd do something like:

get_vars:
call got_vars
vars:
_hello db "hello world", 0
_goodbye db "goodbye world", 0
_answer dd 42
...

and for convenience:

%define hello ebp +  _hello - vars
%define hello ebp +  _goodbye - vars
%define hello ebp +  _answer - vars
...

Then you can do...

jmp get_vars
got_vars:
pop ebp

mov ebx, [answer]

But they don't have an "offset", so you'll have to use "lea".

lea esi, [hello]
call print_it  ; assuming "print_it" takes its parameter in esi

If a routine takes its parameter on the stack, you'll have to...

lea eax, [goodbye]
push eax
call ...
; clean up stack, or not...
...

I don't know if that'll be any help to you. PITA to set up, but it goes okay after that... May not be appropriate for what you're doing.

Best,
Frank


David

  • Guest
Re: Is there alternative code for the ORG directive?
« Reply #7 on: February 27, 2010, 01:23:25 AM »
Thanks Frank! That is really appreciated!

David