仅调用打印msg1,为何我的x86-64汇编代码输出全部内容?
问题原因及解决方法
核心问题出在sys_write系统调用的长度参数设置错误,或者字符串长度计算有误,导致系统从msg1的地址开始,输出了超出预期的内存内容(包括后续的msg2、msg3)。具体分析和修复如下:
1. 检查sys_write的长度参数
x86-64 Linux下的sys_write系统调用,第三个参数(存在rdx寄存器)必须精确指定要输出的字节数。如果你的代码里:
- 错误地将
rdx设为从msg1到数据段末尾的总长度(比如用msg3 - msg1作为长度) - 或者没有为每个字符串单独定义长度,直接用了过大的数值
系统就会从msg1的内存地址开始,连续输出对应长度的字节,自然会把紧挨着的msg2、msg3也一并打印出来。
2. 正确定义字符串及长度
给每个字符串单独定义对应的长度,是最稳妥的做法,示例代码如下:
section .data msg1 db 'Loading...', 0xA ; 0xA是换行符 len1 equ $ - msg1 ; $代表当前地址,计算msg1的字节数 msg2 db 'Loading..', 0xA len2 equ $ - msg2 msg3 db 'Loading.', 0xA len3 equ $ - msg3 section .text global _start _start: ; 仅打印msg1 mov rax, 1 ; sys_write的系统调用号(x86-64 Linux中为1) mov rdi, 1 ; 文件描述符1对应标准输出(stdout) mov rsi, msg1 ; 指向msg1的内存地址 mov rdx, len1 ; 仅输出msg1的长度 syscall ; 退出程序(别忘了加这个,否则会执行后续内存里的垃圾指令) mov rax, 60 ; sys_exit的系统调用号 mov rdi, 0 ; 退出码0代表正常退出 syscall
3. 额外注意:程序退出逻辑
如果你的代码里没有调用sys_exit,程序执行完sys_write后会继续执行后续内存中的指令,可能会触发意外的系统调用或行为,也可能间接导致输出异常。所以一定要在完成预期操作后,调用sys_exit终止程序。
内容的提问来源于stack exchange,提问作者manolidisS
相关产品推荐
相关产品推荐

