为何NASM中相同数值在系统调用中执行不同操作?
问题解析
你混淆的核心点在于:Linux系统调用的行为由EAX寄存器存储的系统调用号决定,其他寄存器的数值是对应调用的参数,数值本身的含义完全取决于当前执行的系统调用。
你写的代码用的是32位Linux系统调用接口(通过int 0x80触发),它遵循固定的寄存器约定:
EAX:存储要调用的系统调用编号EBX/ECX/EDX等:存储对应系统调用的参数,参数顺序由具体调用定义
针对你的代码逐段解释:
第一次系统调用(打印字符串)
mov eax, 4 ; sys_write call mov ebx, 1 ; stdout mov ecx, msg mov edx, msg_L int 0x80 ; call kernel
这里EAX=4告诉内核要执行sys_write系统调用(该调用的作用是向文件描述符写入数据)。对于sys_write来说,EBX是第一个参数——目标文件描述符:
- 1是标准输出(stdout)的固定文件描述符编号,所以此时
EBX=1的含义是「把内容写到标准输出」,和sys_exit完全无关。
第二次系统调用(程序退出)
mov eax, 1 ; sys_exit call int 0x80 ; call kernel
这里EAX=1告诉内核要执行sys_exit系统调用(该调用的作用是终止当前进程)。此时EBX是sys_exit的参数(进程退出码),你代码里没显式设置,但内核会忽略或者使用默认值。
总结
数值1的含义完全由它所在的寄存器,以及当前EAX指定的系统调用决定:
- 当
EAX=4(sys_write)时,EBX=1是文件描述符 - 当
EAX=1(sys_exit)时,EAX=1是系统调用编号,此时EBX的数值才是退出码(你代码里没设置,不影响退出行为)
另外补充:你标注的是x86_64汇编,但实际用的是32位系统调用接口。x86_64原生的系统调用应该用syscall指令,寄存器约定是RDI/RSI/RDX等,系统调用编号也和32位不同(比如sys_write是1,sys_exit是60),不过这是另一个话题了。
内容的提问来源于stack exchange,提问作者Zsargul
相关产品推荐
相关产品推荐

