例如:
在文件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
.
最佳答案
这取决于。你的程序有几个常量:
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 k1
ARM 家族有一个强大的设计,可以直接加载大多数常量:任何 8 位常量值都可以旋转任意偶数次。参见 this第 2-25 页。
声明中有一个不那么明显但完全不同的项目:
printf("%d", b+c);
根据现代 C 语义,字符串 %d
是一个包含三个 char
的常量数组。大多数现代实现会将其存储在只读存储器中,因此尝试更改它会导致 SEGFAULT,这是一个低级别的 CPU 错误,通常会导致程序立即中止。
.psect rodata
s1 db '%', 'd', 0
.psect code
mov eax s1
push eax
关于c++ - 常量数据存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36803471/