Если вы компилируете C в 32-битный код с параметрами GCC по умолчанию (не -mregparm=3
, как использует ядро Linux), то при вводе функции первый аргумент находится в стеке чуть выше адреса возврата (в * 1002). *), но это смещение изменяется после push
чего-либо или перемещения ESP.
Вы можете использовать [ebp+8]
после установки традиционного указателя стека (который не изменяется во время функции, даже когда ESP делает).
Например, int asm_function(int)
может быть реализовано как:
;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
Для каждого параметра после этого просто добавьте еще один 4
(то есть для второго параметра используйте [ebp+12]
). Как вы можете видеть, установка EBP в качестве указателя кадра добавляет много накладных расходов для крошечных функций.
В некоторых не-ELF системах / ABI перед символами C ставится начальный знак подчеркивания, поэтому вы должны объявить оба asm_function
и _asm_function
чтобы ваш код был примерно эквивалентен для этих ABI, например:
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