考虑以下一行:
int v[100];
此行分配100*sizeof(int)
个内存字节。但是如果我们正在寻找这条线的反汇编,那么它背后就没有代码了。那么在没有机器指令的情况下执行内存分配?我很困惑......
答案 0 :(得分:5)
这取决于上下文,但你很可能在谈论堆栈分配的内存/自动变量,如下所示:
int fn()
{
int v[100];
...
}
如果你看一下fn
的反汇编,你应该在函数序言中注意到从esp
寄存器中减去了一些值。
例如,
sub esp, 190h
这是您正在寻找的分配。该变量存储在堆栈中,因此通过移动堆栈指针esp
,您已经清除了它的空间。
答案 1 :(得分:0)
在编译器中,局部变量分配变为alloca
(或“堆栈分配”),假设变量不是“未使用且完全删除”,通常通过减去所需的总大小来完成从函数开头的堆栈指针开始,并在函数末尾添加(或以其他方式恢复堆栈指针)。
对于像上述那样的函数,这是“LLVM IR”(IR = Intermedia Representation):
define i32 @fn() #0 {
%v = alloca [100 x i32], align 16
ret i32 42
}
在x86-64汇编程序中,它变为:
fn: # @fn
pushq %rbp
movq %rsp, %rbp
subq $272, %rsp # imm = 0x110
movl $42, %eax
addq $272, %rsp # imm = 0x110
popq %rbp
retq
(不要问我为什么它是272字节,而不是400 - 我真的不知道!)
如果我们启用优化,使用-O2,它将变为:
fn: # @fn
.cfi_startproc
movl $42, %eax
retq
换句话说,堆栈分配完全消失了。
源代码:
int fn()
{
int v[100];
return 42;
}