Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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
C 带优化的反汇编代码局部变量保存在哪里_C_Gdb_Disassembly - Fatal编程技术网

C 带优化的反汇编代码局部变量保存在哪里

C 带优化的反汇编代码局部变量保存在哪里,c,gdb,disassembly,C,Gdb,Disassembly,我是新来的装配工。我正在研究使用-g和-O3 fiag(优化)编译代码的差异 在优化代码的情况下,反汇编代码不会显示局部变量存储在堆栈上?我的理解是,无论何时调用任何函数,它都会跟踪堆栈上的局部变量,并在执行下一个函数时移动到下一个堆栈帧 下面是优化版本的反汇编代码 (gdb) disassemble main Dump of assembler code for function main: 0x00000000004004d0 <+0>: mov $0x1e,

我是新来的装配工。我正在研究使用-g和-O3 fiag(优化)编译代码的差异

在优化代码的情况下,反汇编代码不会显示局部变量存储在堆栈上?我的理解是,无论何时调用任何函数,它都会跟踪堆栈上的局部变量,并在执行下一个函数时移动到下一个堆栈帧

下面是优化版本的反汇编代码

(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004d0 <+0>:     mov    $0x1e,%eax
   0x00000000004004d5 <+5>:     retq
End of assembler dump.
(gdb) disassemble foo
Dump of assembler code for function foo:
   0x00000000004004c0 <+0>:     lea    (%rsi,%rdi,1),%eax
   0x00000000004004c3 <+3>:     retq
End of assembler dump.

C没有关于局部变量必须存在于何处的规则——它们可以存在于堆栈、寄存器、内存中,也可以完全忽略

在您的示例中,您的大多数局部变量似乎已完全优化。在
-O3
gcc
中,如果局部变量只是偶然的临时变量,则会主动将变量移动到寄存器中,删除未使用的变量,并完全跳过它们。例如,在
foo
中,
gcc
将优化方法
c
,并将加法结果直接存储在结果寄存器
%eax
中。请注意,它根本不会将
c=0;
编译到输出中,因为它知道
c
会被下一条语句阻塞


main
中,
z
y
在输入
foo
时具有已知的值,因此您的编译器只需内联
foo
的定义。常量折叠和传播将
main
简化为
返回30;
,这根本不需要局部变量-这是您在t中看到的输出程序集(
0x1e
=30)。

C没有关于局部变量必须存在的位置的规则-它们可以存在于堆栈、寄存器、内存中,也可以完全省略

在您的示例中,您的大多数局部变量似乎已完全优化。在
-O3
gcc
中,如果局部变量只是偶然的临时变量,则会主动将变量移动到寄存器中,删除未使用的变量,并完全跳过它们。例如,在
foo
中,
gcc
将优化方法
c
,并将加法结果直接存储在结果寄存器
%eax
中。请注意,它根本不会将
c=0;
编译到输出中,因为它知道
c
会被下一条语句阻塞


main
中,
z
y
在输入
foo
时具有已知的值,因此您的编译器只需内联
foo
的定义。常量折叠和传播将
main
简化为
返回30;
,这根本不需要局部变量-这是您在t中看到的输出汇编(
0x1e
=30)。

编译器注意到
foo()
是一个可以内联编译的简单函数。然后它看到所有参数都是常量,因此它计算了结果。因此,您的
main()
函数已优化为等效于:

int main() {
    return 30;
}
$0x1e
是十六进制的数字
30

编译
foo()
时删除了变量
c
,并将其编译为:

int foo(int a, int b) {
    return a + b;
}

参数被传递到寄存器
RSI
RDI
,它们被添加,总和被放入
EAX
中以返回。

编译器注意到
foo()
是一个简单的函数,可以内联编译。然后它看到所有参数都是常数,因此计算结果。因此,您的
main()
函数已优化为等效的:

int main() {
    return 30;
}
$0x1e
是十六进制的数字
30

编译
foo()
时删除了变量
c
,并将其编译为:

int foo(int a, int b) {
    return a + b;
}

参数被传递到寄存器
RSI
RDI
,并被添加,总和被放入
EAX
中返回。

局部变量可以保存在寄存器中。如果您想要一个有用的解释,您需要显示函数的源代码,然后有人可以解释如何存储局部变量ed.这是源代码。局部变量可以保存在寄存器中。如果你想要一个有用的解释,你需要显示函数的源代码,然后有人可以解释局部变量是如何存储的。这是源代码。