【问题标题】:Confused by strace output of a simple helloworld nasm program对一个简单的 helloworld nasm 程序的 strace 输出感到困惑
【发布时间】:2019-09-09 08:46:52
【问题描述】:

我在this page 找到了一个小型 helloworld nasm 程序。

它可以在我的 Debian 上轻松编译/链接/运行,没有任何问题。源代码复制在本文末尾。

> # 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 ##

我无法理解的:

  1. write() 行对我来说看起来很奇怪。是不是应该这样:

    write(1, "hello, world!", 14) = 14
    

    为什么它写入文件描述符 0(STDIN) 而不是 1(STDOUT)?和 如果我 strace 从 hello.c 编译另一个类似的 hello,我做到了 找到预期的行:

    write(1, "hello\n", 6hello) = 6
    

    那么,nasm 程序或 strace 出了什么问题?

  2. stat()的返回值为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

【问题讨论】:

标签: assembly system-calls strace


【解决方案1】:

您正在使用旧的系统调用接口。请改用syscall

根据"bug report",4.26 之前的 strace 无法正确跟踪该接口。
它需要 5.3 或 linux-next 内核。

【讨论】:

    【解决方案2】:

    如果您想在 64 位系统上执行和跟踪具有传统调用约定 (INT 0x80) 的 32 位程序,请将其汇编并链接为 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)                                = ?
    >
    

    【讨论】:

      猜你喜欢
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多