像下面这样简单地编码C文件:
int main()
{
int a = 999;
return 0;
}
使用gcc进行编译和链接后,它将生成一个可执行文件(例如.exe,.out)
但是当我使用某些编辑器打开(不运行)可执行文件时,我找不到变量'a'的值,即999的十六进制值为0x3E7。
我的问题是:
P.S:我对.data .bss .text .etc和汇编语言等内存部分有一点了解。甚至我无法使用ollydbg找到它。
答案 0 :(得分:5)
编译器没有理由将值999
放在任何地方,因为它没有在任何地方使用。不管999
是否在内存中,程序都具有相同的可观察行为。
ISO / IEC 9899:TC2-5.1.2.3程序执行:
- 在抽象机中,所有表达式均按语义指定的方式求值。 如果实际实现可以推断出未使用表达式的值并且没有产生所需的副作用(包括由调用函数或访问易失性对象引起的副作用),则无需评估表达式的一部分。
答案 1 :(得分:4)
优化的重要功能之一是删除未使用的东西。程序的行为完全不依赖于 calculate_averages(input.csv ,output.csv)AttributeError: 'builtin_function_or_method' object has no attribute 'csv'
,并且999
不是a
,因此该赋值不是任何可见副作用的一部分,并且程序完全等同于volatile
以asm格式查看编译器输出要容易得多。
在Godbolt编译器资源管理器上,您可以对其进行设置,以便同时在不同的窗格中看到int main(){return 0;}
和gcc -O0
的asm输出。 https://godbolt.org/z/wNHEnN。
gcc -O1
在mov DWORD PTR [rbp-4], 999
,还有堆栈框架设置绒毛。因此,-O0
输出将以-O0
作为999
指令的双字立即数操作数。该变量是局部变量,因此您不会在mov
或.data
部分中找到它的符号表条目(就像使用带有静态初始值设定项的全局变量一样)。
有关查看编译器输出的更多信息,另请参见How to remove "noise" from GCC/clang assembly output?。