#include <stdio.h>
int main()
{
int i = 10;
return 0;
}
在上面的程序中,值10究竟存储在哪里?
我知道变量I存储在堆栈中。堆栈在运行时填充。
10是一个常量,因此编译器将在程序的可执行部分直接使用数字10作为CPU指令的一部分。
下面是gcc
在我的系统上生成的程序集:
movl $10, -4(%rbp)
(4
是因为int
是4字节长)
请注意,所有这些都是实现的一部分,但以上是在实践中发生的。语言本身并没有规定这些细节。
10
是编译器在编译时生成的"文字"。然后它会被赋值给堆栈上的变量。像
mov eax, 10;
mov [0x12345678], eax;
虽然这是伪代码,但它将为变量i
(地址在这里是0x12345678)分配值10
,该值以前存储在eax
中。
"堆栈"是操作系统为程序留出的一块内存区域,与"堆"、全局变量和可执行代码分开。
调用函数时,有代码将参数压入堆栈,然后为局部变量留出空间。当函数返回这个空间时,所有的参数都从堆栈中"弹出",所以内存可以被下一个函数重用。
这是一个非常基本和粗略的描述,许多细节在系统和编译器之间是不同的。
将有一个明确的机器码指令设置i
。
类似:
MOV AL, 10
编译和链接后,您的可执行文件包含多个段。这两种类型的片段是:
- 文本段-包含实际代码
- 数据段-包含静态数据
(也有其他类型)
值10要么存储在文本段中(作为将10设置为特定地址或寄存器的指令),要么作为数据段中的数据存储(由代码检索并存储在特定地址/寄存器中)。
编译器决定什么是最好的(对于给定的编译标志最有效)。但我认为它是"存储"在一个文本段的值10是相当简单的"创建在代码"(如一些其他答案所示)。
更复杂的数据(结构体,字符串等)通常存储在数据段中。
值10存储在包含源代码的物理源文件中。在执行过程中,该值被传递给一个名为i
的变量,该变量具有自动存储持续时间,类型为int
。这才是最重要的。在通用编程语言(如c)领域,任何进一步的问题都是无效的。
如果你愿意,我宁愿不"给人一条鱼"。你可以自己查看:
拿出你的代码并从中创建一个目标文件:
> gcc -c file.c -o file.o
然后对生成的文件执行对象转储:
> objdump -d file.o
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: c7 45 fc 0f 00 00 00 movl $0xa,-0x4(%rbp) // Right here you can see
// the raw value 0xa (10)
// being set, so it's in the
// .text section