Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux gdb似乎会影响函数返回值';它存储在$eax中?_Linux_Gcc_Gdb_Return_Printf - Fatal编程技术网

Linux gdb似乎会影响函数返回值';它存储在$eax中?

Linux gdb似乎会影响函数返回值';它存储在$eax中?,linux,gcc,gdb,return,printf,Linux,Gcc,Gdb,Return,Printf,“printf”返回实际打印的字符数,因此我有: #include<stdio.h> int main() { printf("1"); printf("55555"); printf("10________"); printf("13___________"); printf("18________________"); printf("28__________________________"); } 然后我尝试在gdb中调试它并检查gdb的返回值: (

“printf”返回实际打印的字符数,因此我有:

#include<stdio.h>
int main()
{
  printf("1");
  printf("55555");
  printf("10________");
  printf("13___________");
  printf("18________________");
  printf("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值并不像我期望的那样。后面的值似乎是正确的。 为什么会这样?为什么first printf不将“1”返回到$eax?我想c风格的ABI将返回值存储在$eax中,对吗


感谢

gcc可以用更高效的代码替换对
printf
的调用,例如对
put
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>
(gdb)disass/m main
主功能的汇编程序代码转储:
3   {
0x000000000040057d:推送%rbp
0x000000000040057e:mov%rsp,%rbp
4 printf(“1”);
0x0000000000400581:mov$0x31,%edi
0x0000000000400586:callq 0x400450
5 printf(“55555”);
0x000000000040058b:mov$0x400664,%edi
0x0000000000400590:mov$0x0,%eax
0x0000000000400595:callq 0x400460

要让gcc始终生成对
printf
的调用,您可以使用
-fno-builtin-printf
选项。

谢谢,-fno-builtin-printf对我有效。我只是感到困惑,我没有使用“-O”选项或进行任何优化,为什么gcc仍然进行一些优化?如何手动完全禁用它?即使使用
-O0
,gcc仍然会用等效的、更高效的代码替换标准函数,如
printf
strcpy
,除非您为它指定
-fno内置名
无内置名
选项。
(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>