#include <stdio.h>
int main()
{
int i = 10;
return 0;
}
在上面的程序中,究竟存储了值10?
我理解变量i存储在堆栈中。堆栈在运行时填充。从“究竟”10来自哪里。
答案 0 :(得分:5)
10是常量,因此编译器将直接在程序的可执行部分中使用数字10作为CPU指令的一部分。
以下是使用gcc
在我的系统上生成的程序集:
movl $10, -4(%rbp)
(4
是因为int
长4个字节)
请注意,所有这些都是实现的一部分,但上述情况在实践中发生。语言本身没有指定这些细节。
答案 1 :(得分:4)
10
是一个“文字”,它将在编译期间由编译器生成。然后它将被分配给堆栈上的变量。像
mov eax, 10;
mov [0x12345678], eax;
这是pseude-code,但会为您的变量i
(地址在此处为0x12345678)指定值10
,之前存储在eax
中。
答案 2 :(得分:2)
“堆栈”是由程序的操作系统留出的内存区域,与“堆”以及全局变量和可执行代码分开。
当调用函数时,有代码将参数推送到堆栈,然后为局部变量留出空间。当函数返回此空间并且所有参数都从堆栈“弹出”时,下一个函数可以重用内存。
这是一个非常基本和粗略的描述,很多细节在系统和编译器之间有所不同。
答案 3 :(得分:1)
将有一个明确的机器代码指令设置i
。
类似的东西:
MOV AL, 10
答案 4 :(得分:1)
编译和链接后,您的可执行文件包含多个segments。这些细分的两种类型是:
(还有其他类型)
值10存储在文本段中(作为将10设置为特定地址或寄存器的指令),或存储为数据段中的数据(由代码检索并存储在特定地址/寄存器)。
编译器决定什么是最好的(对于给定的编译标志最有效)。但我认为它“存储”在一个文本段中,因为值10很容易“在代码中创建”(如其他一些答案所示)。
更复杂的数据(结构,字符串等)通常存储在数据段中。
答案 5 :(得分:1)
值10存储在包含源代码的物理源文件中。在执行期间,该值将传输到名为i
的变量,该变量具有自动存储持续时间,并且类型为int
。这就是最重要的。任何进一步的问题在诸如C等通用编程语言领域都不具有生产力。
请注意大多数答案如何提及编译器?如果an interpreter is used to translate C source code directly into behaviour怎么办?这些答案仍然有效吗?
答案 6 :(得分:1)
如果你愿意的话,我宁可不“给男人一条鱼”......你可以亲自检查一下:
获取代码并从中创建目标文件:
> 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