对一个简单的 helloworld nasm 程序的 strace 输出感到困惑
Confused by strace output of a simple helloworld nasm program
我在 this page 找到了一个小的 helloworld nasm 程序。
它可以在我的 Debian 上轻松 compiled/linkd/run 没有任何问题。本post末尾复制源码。
> # Compile
> nasm -f elf64 hello.asm -o hello.o
> # Link
> ld hello.o -o hello
> # Run
> ./hello
但是当我对其执行 strace 时,输出让我感到困惑。
> ## output of 'strace ./hello' ##
>
> execve("./hello", ["./hello"], 0x7ffc9dadd930 /* 89 vars */) = 0
> stat(NULL, Hello, world!
> NULL) = 14
> write(0, NULL, 14) = ?
> +++ exited with 0 +++
>
> ## end of output ##
不明白的地方:
write() 行对我来说很奇怪。不应该是这样的:
write(1, "hello, world!", 14) = 14
为什么它写入文件描述符 0(STDIN) 而不是 1(STDOUT)?和
如果我 strace 从 hello.c 编译的另一个类似的 hello,我做了
找到预期的行:
write(1, "hello\n", 6hello) = 6
那么,nasm 程序或 strace 有什么问题?
stat()的return值为14,是字符串长度,还是错误号?
hello.asm的源码复制到这里:
; 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 eax,4 ; 'write' system call = 4
mov ebx,1 ; file descriptor 1 = STDOUT
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Terminate program
mov eax,1 ; 'exit' system call
mov ebx,0 ; exit with error code 0
int 80h ; call the kernel
您正在使用旧系统调用接口。请改用 syscall
。
根据此 "bug report",4.26 之前的 strace 无法正确跟踪该接口。
它需要 5.3 或 linux-next 内核。
如果你想在 64 位系统上执行和跟踪具有旧调用约定 (INT 0x80) 的 32 位程序,assemble 和 link 它作为 32 位:
; # Compile
; nasm -f elf hello.asm -o hello.o
; # Link
; ld hello.o -o hello -m elf_i386
; # Run
; ./hello
; # Trace
; strace ./hello
> ld hello.o -o hello -m elf_i386
> ./hello
Hello world!
> strace ./hello
execve("./hello", ["./hello"], [/* 57 vars */]) = 0
[ Process PID=15247 runs in 32 bit mode. ]
write(1, "Hello world!\n", 13Hello world!) = 13
_exit(0) = ?
>
我在 this page 找到了一个小的 helloworld nasm 程序。
它可以在我的 Debian 上轻松 compiled/linkd/run 没有任何问题。本post末尾复制源码。
> # Compile
> nasm -f elf64 hello.asm -o hello.o
> # Link
> ld hello.o -o hello
> # Run
> ./hello
但是当我对其执行 strace 时,输出让我感到困惑。
> ## output of 'strace ./hello' ##
>
> execve("./hello", ["./hello"], 0x7ffc9dadd930 /* 89 vars */) = 0
> stat(NULL, Hello, world!
> NULL) = 14
> write(0, NULL, 14) = ?
> +++ exited with 0 +++
>
> ## end of output ##
不明白的地方:
write() 行对我来说很奇怪。不应该是这样的:
write(1, "hello, world!", 14) = 14
为什么它写入文件描述符 0(STDIN) 而不是 1(STDOUT)?和 如果我 strace 从 hello.c 编译的另一个类似的 hello,我做了 找到预期的行:
write(1, "hello\n", 6hello) = 6
那么,nasm 程序或 strace 有什么问题?
stat()的return值为14,是字符串长度,还是错误号?
hello.asm的源码复制到这里:
; 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 eax,4 ; 'write' system call = 4
mov ebx,1 ; file descriptor 1 = STDOUT
mov ecx,hello ; string to write
mov edx,helloLen ; length of string to write
int 80h ; call the kernel
; Terminate program
mov eax,1 ; 'exit' system call
mov ebx,0 ; exit with error code 0
int 80h ; call the kernel
您正在使用旧系统调用接口。请改用 syscall
。
根据此 "bug report",4.26 之前的 strace 无法正确跟踪该接口。
它需要 5.3 或 linux-next 内核。
如果你想在 64 位系统上执行和跟踪具有旧调用约定 (INT 0x80) 的 32 位程序,assemble 和 link 它作为 32 位:
; # Compile
; nasm -f elf hello.asm -o hello.o
; # Link
; ld hello.o -o hello -m elf_i386
; # Run
; ./hello
; # Trace
; strace ./hello
> ld hello.o -o hello -m elf_i386
> ./hello
Hello world!
> strace ./hello
execve("./hello", ["./hello"], [/* 57 vars */]) = 0
[ Process PID=15247 runs in 32 bit mode. ]
write(1, "Hello world!\n", 13Hello world!) = 13
_exit(0) = ?
>