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

关于NASM编写的HelloWorld程序strace输出异常的技术疑问

问题根源:32位系统调用与64位环境不兼容

这问题我碰到过好几次了——核心原因是你的NASM代码用了32位的int 80h系统调用接口,但却编译成了64位目标文件,两者的调用规则完全不匹配,才导致strace输出一堆看似异常的内容。

为什么strace会显示write(0, NULL, 14)?

在32位Linux系统调用中,我们用int 80h,系统调用号存在eax,参数依次存在ebx、ecx、edx等寄存器里。但64位Linux下,正确的系统调用指令是syscall,并且寄存器映射完全不同:系统调用号存在rax,第一个参数在rdi,第二个在rsi,第三个在rdx...

当你把32位代码编译成64位程序后,执行int 80h时,内核会按照32位规则去解析寄存器,但64位寄存器的高32位可能有垃圾值,或者strace在64位环境下解析32位系统调用的参数时出现错位,所以才会把原本要传给write的ebx=1(STDOUT)解析成了文件描述符0(STDIN),其他参数也乱成了NULL,这完全是解析错位导致的,不是你的代码逻辑写错了,只是架构不匹配。

关于stat(NULL, ...) = 14的疑问

那个14不是错误码,而是你字符串Hello world!\n的长度(刚好14个字符)。因为系统调用被错误解析,strace把原本write系统调用的返回值(写入的字节数14)当成了stat系统调用的返回值,而stat的参数也是乱解析出来的,所以看起来莫名其妙。

两种修复方案

方案1:编译成32位程序

如果你想保留32位的int 80h代码,只需要修改编译和链接命令,生成32位可执行文件:

nasm -f elf32 hello.asm -o hello.o
ld -m elf_i386 hello.o -o hello

64位Debian默认支持运行32位程序(如果没装可以用apt install libc6-i386安装依赖),运行后strace会输出正常的write(1, "Hello world!\n", 14) = 14。

方案2:改成64位系统调用代码

更推荐的方式是适配64位环境,使用syscall指令和64位系统调用号:

; Define variables in the data section
SECTION .DATA
hello: db 'Hello world!',10
helloLen: equ $-hello

; Code goes in the text section
SECTION .TEXT
GLOBAL _start
_start:
    mov rax, 1          ; 64位write系统调用号是1(32位是4)
    mov rdi, 1          ; file descriptor 1 = STDOUT
    mov rsi, hello      ; string to write
    mov rdx, helloLen   ; length of string to write
    syscall             ; call 64-bit kernel interface

    ; Terminate program
    mov rax, 60         ; 64位exit系统调用号是60(32位是1)
    mov rdi, 0          ; exit with error code 0
    syscall

用你原来的命令编译链接:

nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello

运行后strace会输出符合预期的结果:

execve("./hello", ["./hello"], 0x7ffc... /* 89 vars */) = 0
write(1, "Hello world!\n", 14) = 14
exit(0) = ?
+++ exited with 0 +++

总结

不是strace的问题,是你的代码使用的系统调用接口和编译目标架构不匹配导致的。只要调整代码或者编译方式,就能解决这个异常输出的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:56:44