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
Code: Select all
mov eax, printk
call eax
Code: Select all
mov DWORD[mem32], printk
call DWORD[mem32]
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.