“printf”返回实际打印的字符数,所以我有:
#include<stdio.h>
int main()
{
printf("1");
printf("55555");
printf("10________");
printf("13___________");
printf("18________________");
printf("28__________________________");
}
这个程序会输出
15555510________13___________18________________28__________________________
然后我尝试在gdb中调试,查看gdb的返回值:
(gdb) b main
Breakpoint 1 at 0x804844c: file testp.c, line 4.
(gdb) r
Starting program: /home/a/cpp/a.out
Breakpoint 1, main () at testp.c:4
4 printf("1");
(gdb) n # will return "1" to $eax
5 printf("55555");
(gdb) p $eax # I expect it will print "1" here, wrong!
$1 = 49
(gdb) n
6 printf("10________");
(gdb) p $eax # I expect it will print "5" here, right!
$2 = 5
(gdb) n
7 printf("13____________");
(gdb) p $eax # I expect it will print "10" here, right!
$3 = 10
如您所见,当第一个 printf 运行时,$eax 值与我的预期不同。后来的值似乎是正确的。 为什么是这样?为什么首先 printf 不向 $eax 返回“1”?我想 c 风格的 ABI 将返回值存储在 $eax 中,对吗?
谢谢
最佳答案
gcc 可以用更高效的代码替换对 printf
的调用,例如对 puts
或 putchar
的调用,在优化获胜的某些情况下不要更改函数的记录行为(例如,当输出不需要进行任何格式化并且您不使用返回值时)。这就是这里发生的事情。您在 %eax 中看到 49,因为 putchar
返回输出的字符或 EOF
。
(gdb) disass /m main
Dump of assembler code for function main:
3 {
0x000000000040057d <+0>: push %rbp
0x000000000040057e <+1>: mov %rsp,%rbp
4 printf("1");
0x0000000000400581 <+4>: mov $0x31,%edi
0x0000000000400586 <+9>: callq 0x400450 <putchar@plt>
5 printf("55555");
0x000000000040058b <+14>: mov $0x400664,%edi
0x0000000000400590 <+19>: mov $0x0,%eax
0x0000000000400595 <+24>: callq 0x400460 <printf@plt>
要让 gcc 始终生成对 printf
的调用,您可以使用 -fno-builtin-printf
选项。
关于linux - gdb 似乎影响存储在 $eax 中的函数返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40106206/