Page 1 of 1

Assembly CALL instruction on extern labels

Posted: Tue Aug 25, 2020 12:33 pm
by iman
Hi.

I had a discussion some days ago (viewtopic.php?f=1&t=37142) regarding an issue to bring up the AP cpu with trampoline code. If you scroll down, you would see that in the end, I solved the problem, but something new draw my attention for a while. It's about how NASM perform a CALL instruction on an extern label.
So, basically, I had some C and assembly routines specified for my BSP cpu. In my trampoline code to wake up the AP cpu, I would like to have one of those routines (printing on screen) at hand. I labeled it as extern in the beginning of the code.
If I call it as

Code: Select all

call printk
it gives me a triple fault, but if instead I do

Code: Select all

mov eax, printk
call eax
or

Code: Select all

mov DWORD[mem32], printk
call DWORD[mem32]
it is completely fine and flawless.
Of course the machine code for the first call would be as E8 rel32 and for the second or third call would be something like FF r/m32.
The trampoline code itself is based at physical address 0x8000 (I put it here and jump into it when I switch the AP cpu to protected mode), but I always assumed that something like call printk, will perform the right jump into the specified address, while apparently is not the case.
The question:
Even if it is fine to perform the call instruction with the use of FF machine code, why a call instruction directly on label (E8 machine code) would be ended up in kernel crash? It puzzles me.

Best.
Iman.

Re: Assembly CALL instruction on extern labels

Posted: Tue Aug 25, 2020 12:51 pm
by Gigasoft
If you have copied the code to another location, the operands of direct near jumps and calls will of course be relative to the new location and therefore not point to the intended target address.

Re: Assembly CALL instruction on extern labels

Posted: Tue Aug 25, 2020 12:59 pm
by iman
Gigasoft wrote:If you have copied the code to another location, the operands of direct near jumps and calls will of course be relative to the new location and therefore not point to the intended target address.
I did not put ORG 0x8000 in the beginning of the assembly code but instead copied it directly. Does it still make near jumps and calls relative to the new position?

Re: Assembly CALL instruction on extern labels

Posted: Tue Aug 25, 2020 2:31 pm
by Octocontrabass
Yes. Direct near jumps and calls are always dependent on the position. These instructions only store the difference between the current location and the destination, so if you move the code containing the jump or call instruction to a different address, the destination address also changes.

If you tell the linker that the code will be located at 0x8000 when it runs, the linker will calculate the correct difference so the code can run when you move it to 0x8000.

ORG does not work unless you're using NASM to link your code to a flat binary.