How to pass a variable from a C program to a assembly function.
Example:
main.c:
void main() {
unsigned int passthis = 42
extern asm_function();
asm_function(passthis)
}
main.asm:
bits 32
global start
section .text
asm_function:
...
How do I access passthis
within asm_function
.
Edit: Probably should've mentioned i'm not using a OS, i'm compiling using a i686-elf cross compiler and am going to use it as a kernel.
If you compile your C into 32-bit code with the default GCC options (not -mregparm=3
like the Linux kernel uses), then on function entry the first argument is on the stack just above the return address (at [esp+4]
), but that offset changes after you push
anything or move ESP around.
You can use [ebp+8]
after setting up a traditional stack pointer (which doesn't change during the function even when ESP does).
For example, int asm_function(int)
can be implemented as:
;bits 32 ; unneeded, nasm -felf32 implies this.
global asm_function ; include asm_function in ELF .o symbol table for linking
section .text
asm_function:
push ebp
mov ebp, esp
mov eax, [ebp+8] ; return the first argument
mov esp, ebp
pop ebp
ret
For each parameter after this, just simply add another 4
(i.e. for the 2nd parameter, use [ebp+12]
). As you can see, setting up EBP as a frame pointer adds a lot of overhead for tiny functions.
Some non-ELF systems/ABIs prepend a leading underscore to C symbol names, so you should declare both asm_function
and _asm_function
for your code to be roughly equivalent across these ABIs, like so:
global _asm_function
global asm_function ; make both names of the function global
section .text
_asm_function:
asm_function: ; make both symbols point to the same place
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov esp, ebp
pop ebp
ret