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

使用sys_write的汇编代码为何无输出且未触发段错误?

问题分析:汇编代码无输出也无段错误的原因

先贴出你的汇编代码方便分析:

.SECTION .data
msg: .string "AAAA"

.SECTION .text
.globl _start
_start:
mov $1, %rax   ; sys_write 系统调用号
mov $1, %rdi   ; 文件描述符:stdout
mov msg, %rsi  ; 错误:传递的是字符串内容而非地址
mov $4, %rdx   ; 写入长度
syscall

1. 为什么没有输出?

核心问题在mov msg, %rsi这一行。以x86-64的NASM语法为例,直接写符号msg会引用该地址存储的数据,而不是地址本身。你的msg指向字符串"AAAA"的首字节(十六进制值0x41),所以这行代码会把0x41加载到%rsi寄存器里——但sys_write系统调用要求%rsi是指向输出缓冲区的指针。

你传递的0x41是用户空间无法访问的低地址,sys_write会直接执行失败(返回值为-EFAULT,对应错误码14),自然不会有任何输出。正确的写法应该是用$msg获取符号地址,或者用lea指令加载有效地址:

mov $msg, %rsi  ; 正确:将msg的地址加载到rsi
; 或者更高效的写法
lea msg, %rsi

2. 为什么没有触发段错误,也不需要显式调用sys_exit?

在Linux的x86-64环境中,_start是程序的特殊入口点,和普通函数逻辑不同:

  • 当_start的指令流执行完毕后,内核会自动接管进程的退出流程,调用exit_group系统调用终止整个进程,不需要你显式写sys_exit调用。
  • 至于没触发段错误:虽然syscall之后没有指令,CPU会尝试执行下一个内存位置的代码,但这个位置要么属于.text段末尾(可能被内核标记为不可执行),要么是未映射的内存,但内核会在进程入口点执行完毕后直接终止进程,不会让非法执行触发的段错误暴露给用户。

总结一下:内核帮你处理了退出,而你的sys_write因为参数错误执行失败,所以才会出现既没输出也没崩溃的情况。

内容的提问来源于stack exchange,提问作者Dan Joe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:05:16