Assembly write系统调用中strace输出中的混合整数和字符串
我想从32位程序集调用write syscall,我现在使用的代码是:Assembly write系统调用中strace输出中的混合整数和字符串,assembly,x86,att,strace,Assembly,X86,Att,Strace,我想从32位程序集调用write syscall,我现在使用的代码是: .section .rodata # read-only data msg: .ascii "hello" # not null-terminated string called "msg" len: .long 5 # length of "msg" .section .text
.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
它编译并正常工作,将字符串“hello”打印到控制台,但当我使用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 +++
我想知道是什么原因导致第三个片段是5hello而不是5。没有,其中的
hello
是程序的实际输出。以下是正在发生的事情:
write(1,“hello”,5
。注意这会转到stderr
。出于某种原因,它还没有打印结束)
write
syscall,因此hello
被打印到stdout
)=5
在您的情况下,
stdout
和stderr
都指同一个终端。重定向strace或您的代码的输出,使它们不会被分散。没有,其中的hello
是您程序的实际输出。重定向strace或代码的输出,这样它们就不会被分散。我真不敢相信我错过了,谢谢。我将在3分钟内接受您的回答我相信strace
钩子将在调用系统调用之前首先输出参数(逻辑上,因为调用可以自由修改参数),然后在返回时使用返回值完成输出。与此同时,作者用“hello”完成了它的工作。@Ped7g:这并不能完全解释为什么strace
不等待打印)=retval
。原因是系统调用可能会阻塞,因此它会在调用之前打印调用内容,在调用之后打印返回内容。通过运行strace sleep 1
可以很容易地看到这一点。当系统调用被信号中断时,strace甚至会打印额外的内容(例如,如果您在nanosleep
或pkill-WINCH sleep
期间打印^z
,则会向它发送一个不起任何作用的信号)。@Jester:我认为它会推迟打印)
因此,中断的系统调用在输出中更为明显(对于选择不使用相同参数重新启动中断的系统调用的使用空间来说,这可能很重要)。或者,这可能与某些系统调用(如nanosleep
)具有输出指针参数有关?