c++ - 常量数据存储在哪里?

标签 c++

例如:

在文件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/

相关文章:

c++ - 如何实现可以用void实例化的智能指针?

c++ - QToolButton 信号和槽

c++ - 简单的 C++ 求和程序

c++ - 限制一个类的实例数

c++ - Qt - 堆栈上有父级的 QObject 如何被删除两次?

c++ - 如果 Matlab 以 GUI 启动,如何从 MEX 文件中检查

c++ - 私有(private)继承出现 "an inaccessible base"错误

c++ - 如何在 std::function 中存储 std::sqrt

c++ - 有效地移动整个内存块

c++ - 数组删除给出 EXC_BAD_ACCESS 错误