[英]how the stack frame works?
我正在閱讀 csapp 和一些代碼(x86-64)讓我感到困惑。
這本書說“pushq %rbp”等於:
subq $8,%rsp
movq %rbp,(%rsp)
c 代碼為:
long P(long x,long y)
{
long u = Q(y);
long v = Q(x);
return u + v;
}
本書給出的匯編代碼的一部分是:
pushq %rbp
pushq %rbx
subq $8,%rsp
'subq' 讓我感到困惑。
為什么會這樣?
堆棧是一塊向下生長的 memory。 memory 中有一個點,由rsp
/ esp
寄存器指示,它是堆棧頂部。 它上面的所有 memory 都被放置在堆棧上的東西占用,而它下面的所有 memory 都是免費的。
如果你想把一些東西放在堆棧上,你需要將rsp
寄存器(這是sub
指令所做的)減少你需要的字節數,並且rsp
現在將指向你需要的新保留區。
讓我們看這個簡單的例子:
rsp
指向地址 100。如上所述 - 使用地址 100 以上的整個 memory,而地址 100 以下的 memory 是免費的。 因此,如果您需要 4 個字節,則將rsp
減少 4,使其指向 96。由於您剛剛減少了rsp
,因此您知道 memory 單元格 96、97、98 和 99 是您的,您可以使用它們。 當您在堆棧上需要更多字節時,您可以再次減少rsp
以獲得更多字節。
有兩種方法將東西放在堆棧上。 1.可以如上圖減少rsp
。 2.你可以使用push
指令,它的作用完全相同,但一步完成: push rax
會將rsp
減少8個字節( rax
寄存器的大小),然后將其值保存在保留區域中。
有時也使用rbp
寄存器對堆棧進行操作。 如果您需要更大的堆棧區域,例如局部變量,您可以在堆棧上保留所需的數量,然后將當前rsp
值保存到rbp
中。 所以rbp
是一種書簽,可以記住您所在區域的位置。 然后你可以push
更多的東西壓入堆棧,而不會丟失分配區域所在的信息。
在離開 function 之前,所有放在堆棧上的東西都需要從中取出。 它是通過與push
相反的pop
指令完成的 - 從堆棧中獲取值並將其移動到寄存器然后增加rsp
。 或者,如果您不需要恢復寄存器值,您可以只增加rsp
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.