write syscall中strace输出中的混合整数和字符串

时间:2016-12-22 15:41:25

标签: assembly x86 att strace

我想从32位汇编调用一个写系统调用,现在使用的代码是:

.section    .rodata             # read-only data
msg:
    .ascii  "hello"             # not null-terminated string called "msg"
len:
    .long   5                   # length of "msg"


.section    .text               # actual runnable code
.globl      _start
.type       _start, @function
_start:
    movl    $4, %eax            # syscall number into eax (4 is write)
    movl    $1, %ebx            # argument number 1 into ebx (stdout)
    movl    $msg, %ecx          # argument number 2 into ecx
    movl    len, %edx           # argument number 3 into edx
    int     $0x80

    movl    $1, %eax            # syscall number into eax (1 is exit)
    movl    $0, %ebx            # argument number 1 into ebx (exit code)
    int     $0x80

它编译并正常工作,打印字符串"你好"到控制台,但当我使用strace来"看到"写入发生后,我得到以下输出:

execve("./main", ["./main"], [/* 86 vars */]) = 0
strace: [ Process PID=22529 runs in 32 bit mode. ]
write(1, "hello", 5hello)                    = 5
exit(0)                                 = ?
+++ exited with 0 +++

我想知道是什么原因导致第三个问题变成了5个而不是5个。

1 个答案:

答案 0 :(得分:3)

没有,hello是你程序的实际输出。以下是发生的事情:

  1. strace截取写入系统调用
  2. strace打印出呼叫名称和参数:write(1, "hello", 5。请注意这是stderr。由于某种原因,它还不打印结束)
  3. 执行write系统调用,因此hello将打印到stdout
  4. strace再次需要获得控制权以便它可以打印返回值,它与给出) = 5的右括号一起打印。
  5. 在您的情况下,stdoutstderr都指向同一个终端。重定向strace或代码的输出,使它们不会散布。