例如:
在demo.c文件中,
#inlcude<stdio.h>
int a = 5;
int main(){
int b=5;
int c=a;
printf("%d", b+c);
return 0;
}对于int a = 5,编译器是否将其转换为虚拟内存地址上的存储0x5,例如const区域中的Ox0000000f,以便对于int c = a,将其转换为类似于movl 0x0000000f %eax的内容
然后,对于int b = 5,数字5不被放入const区域,而是直接转换为汇编指令(如mov $0x5 %ebx )中的直接值。
发布于 2016-04-22 21:34:01
那得看情况。您的程序有几个常量:
int a = 5;这是一个“静态”初始化(在运行前加载程序文本和数据时发生)。该值存储在a保留的内存中,该内存位于读写数据“程序部分”中。如果某些东西改变了a,那么值5就会丢失。
int b=5;这是一个范围有限的局部变量(仅由main())。存储很可能是CPU寄存器或堆栈上的位置。为大多数体系结构生成的指令将在指令中将值5作为“即时数据”,用于x86示例:
mov eax, 5指令保存任意常量的能力是有限的。大多数CPU指令支持较小的常量。“大”常量通常不直接支持。在这种情况下,编译器会将常量存储在内存中并加载它。例如,
.psect rodata
k1 dd 3141592653
.psect code
mov eax k1ARM家族有一个强大的设计,可以直接加载大多数常量:任何8位常量值都可以旋转任意偶数次。见这第2-25页.
声明中有一个不那么明显但完全不同的项目:
printf("%d", b+c);从现代C语义来看,字符串%d是一个由三个char组成的常量数组。大多数现代实现都会将其存储在只读内存中,以便尝试更改它将导致SEGFAULT,这是一个低级CPU错误,通常导致程序立即中止。
.psect rodata
s1 db '%', 'd', 0
.psect code
mov eax s1
push eax发布于 2016-04-22 21:36:20
在OP的程序中,a是一个“初始化”“全局”。我希望它被放置在数据段的初始化部分。参见layout.pdf,http://www.cs.uleth.ca/~holzmann/C/system/memorylayout.gif (来自有关可执行程序(进程)内存布局的更多信息)。a的位置由编译器-链接器二重奏决定。
另一方面,作为自动(堆栈)变量,需要在堆栈段中使用b和c。
尽管如此,编译器/链接器可以自由地执行任何优化,只要所观察到的行为不被违反(“以假乱真”规则到底是什么?)。例如,如果a从未被引用过,那么它可能会被完全优化。
https://stackoverflow.com/questions/36803471
复制相似问题