Search code examples
cassemblymemoryx86calling-convention

How to pass variables to a external assembly function


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.


Solution

  • 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