nasm汇编 linux和macos int 80h调用系统函数的参数传递
linux和macos的汇编中通过 int 80h
软中断来调用系统函数,但是给函数传入的参数方法不同。以下说明32位程序的调用方式。
Linux
对于linux,如果我要调用如下的C语言函数:
sys_write(unsigned int fd, const char * buf, size_t count);
函数参数和寄存器对应关系为:
ebx: fd
ecx: buf
edx: count
然后函数编号对应寄存器 eax
, 函数编号对照表可以参考https://blog.csdn.net/xiaominthere/article/details/17287965
所以汇编中调用sys_write
这个函数来显示一个字符串对应的汇编如下:
section .data
msg db 'Hello'
section .text
__display:
mov edx, 5 ;字符串长度, 对应count参数
mov cdx, msg ;字符串所在地址, 对应buf参数
mov ebx, 1 ;对应fd参数,fd为1时表示stdout, 显示屏
mov eax, 4 ;对应sys_write在linux系统中调用好为4
int 80h
macOS
在macos中,C语言函数的参数不使用寄存器来存放,而是使用stack来存放,参数顺序倒序入栈,总共支持16字节。比如同样的显示字符串功能,在macos中的C函数为:
write(int fd, user_addr_t cbuf, user_size_t nbyte);
因此,函数参数入栈顺序为:
push nbyte
push cbuf
push fd
sub esp 4 ;参数总共要占用16字节,因为这个函数需要3个参数,所以实际占用了 3*4=12个字节,为了填满16字节,这里将stack地址再减去4个字节(stack在内存中由高到底存放,所以是减去)
然后函数编号对应寄存器 eax
, 函数编号对照表可以参考https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master
所以汇编中调用write
这个函数来显示一个字符串对应的汇编如下:
section .data
msg db 'Hello'
section .text
__display:
push dword 5 ;字符串长度, 对应nbyte参数
push dword msg ;字符串所在地址, 对应cbuf参数
push dword 1 ;对应fd参数,fd为1时表示stdout, 显示屏
sub esp, 4 ;填满16字节
mov eax, 4 ;对应sys_write在macos系统中调用好为4
int 80h
无论在linux还是macos中,函数的返回值都最后保存在eax
寄存器中。
参考:
linux调用方式: https://blog.csdn.net/xiaominthere/article/details/17287965
macos调用方式: https://filippo.io/making-system-calls-from-assembly-in-mac-os-x/