link function with other base address

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
ich_will

link function with other base address

Post by ich_will »

How can I link a function into my kernel with another base address, f.e. if I move it later:

Code: Select all

_function:
  jmp f2
f2:
it tryed out (I move the function to 0x500):

_function:
jmp 0x500+(f2-_function)
f2:

but then I can't link it.
Curufir

Re:link function with other base address

Post by Curufir »

The only time you have to worry about addressing, in relation to the jmp instruction, is when you make a far jump (Segment/Selector : Offset). If you aren't changing Segment/Selector then all the offsets should be relative (Any decent assembler will calculate labels as offsets in this scenario) and are therefore unaffected by changes in base address.

Your example would most likely be encoded as 0xEB 0x00 (Note the lack of any absolute address information).

Exactly the same applies to call instructions.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:link function with other base address

Post by Pype.Clicker »

if the function has moved to 0x500, why not simply

Code: Select all

   jmp 0x500
or maybe you mean you copied the whole _function to 0x500 and now you want to branch to F2 in the copy ? In which case i think

Code: Select all

jmp 0x500 + ($ - _function)
should do the trick. If it doesn't, try to put your _function in a dedicated section and use $$ ...

Code: Select all

section copied_function
_function:

     create_the_copy

     jmp 0x500 + ($-$$)
ich_will

Re:link function with other base address

Post by ich_will »

all these possibilities can be assambled with nasm but i can't link it in my kernel:
it prints out:
relocation truncated to fit: DISP16 *ABS*
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:link function with other base address

Post by Pype.Clicker »

well, so it looks you need a 32 bits offset at the linker and issued an operation with a 16bits offset. Make sure you are in the proper [ bits ] mode, etc.
Curufir

Re:link function with other base address

Post by Curufir »

Ok, obviously I was too cryptic.

These:

Code: Select all

jmp 0x500+(f2-_function)
jmp f2
jmp 0x500
jmp 0x500 + ($ - _function)
jmp 0x500 + ($-$$)
ALL get assembled as relative offsets by NASM because ALL of them resolve to:

Code: Select all

jmp immediate
This code (To take one example):

Code: Select all

jmp 0x500
Is totally independent of the base address your code is linked to, or the address it is loaded at. All it says is to jump 0x500 bytes forward from the end of the jump instruction. Exactly the same goes for using labels (Including the pre-defined ones) because labels are also just immediate values.

If you want to start jumping to actual memory addresses then you MUST use a different form of jmp. Out of preference for simplicity just load a register (eax for example) with the appropriate address and do:

Code: Select all

jmp [eax]
ich_will

Re:link function with other base address

Post by ich_will »

That means, i have to know all address (of labels for example), if I want to move the function after linking? Is there no easier way?
ich_will

Re:link function with other base address

Post by ich_will »

I've an idea:

Is it possible to create a section in the linker skript, which is only for this function(s) and have another base address (0x500). Then copy this section to 0x500 and ready? If it is possible I don't know how to code this.
ich_will

Re:link function with other base address

Post by ich_will »

Ok why i will do this is, i want to re-enter realmode, because i'm to stupid to understand how i can do it in another way. My problem is that i've no place in my kernel to setup a 16 bit GDT entry, and I won't recompile etc. my bootloader everytime if I want to change something in my memory maps. So I want to do this in my kernel, in the start.asm (load a new GDT etc., or can I simply load a new in Pmode). see thread: http://www.mega-tokyo.com/forum/index.php?board=1;action=display;threadid=5806

but please don't stop helping me with this thread (copy a function...) perhaps it will be usefull.
Schol-R-LEA

Re:link function with other base address

Post by Schol-R-LEA »

ich_will wrote: That means, i have to know all address (of labels for example), if I want to move the function after linking? Is there no easier way?
No, just the opposite: the only address you need to know is the new function entry point. The rest of the labels are recalculated by the assembler to give an offset relative to the jmp instruction itself, and thus don't need to be changed.

Since the entry point should be at the beginning of the block which you moved the function to, all you need to do is keep track of the new location. If you have more than one such function, you'll probably want a table of some sort for this.
ich_will

Re:link function with other base address

Post by ich_will »

thanks
Post Reply