You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:48:19