Soo 我試圖了解匯編程式如何與堆疊幀等一起作業。我做了一些練習并使用 Intel 表示法用 GDB 反匯編了一些 C 代碼。現在的任務是找出變數“r”是如何通過“main”和“f”函式之間的引數傳遞來計算的。我剛開始學習,有點迷失了這個例子實際上在做什么。關于從哪里開始的任何想法或一些提示?
這是一個與教師合作的遞回程式:
#include <stdio.h>
unsigned int f(unsigned int i) {
if (i>1) {
return i * f(i-1);
} else {
return 1;
}
}
int main() {
unsigned int i=5, r=0;
r = f(i);
printf("i = %d, f(i) = %d\n", i, r);
}
匯編代碼如下所示:
#include <stdio.h>
unsigned int f(unsigned int i) {
1149: f3 0f 1e fa endbr64
114d: 55 push rbp
114e: 48 89 e5 mov rbp,rsp
1151: 48 83 ec 10 sub rsp,0x10
1155: 89 7d fc mov DWORD PTR [rbp-0x4],edi
if (i>1) {
1158: 83 7d fc 01 cmp DWORD PTR [rbp-0x4],0x1
115c: 76 13 jbe 1171 <f 0x28>
return i * f(i-1);
115e: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
1161: 83 e8 01 sub eax,0x1
1164: 89 c7 mov edi,eax
1166: e8 de ff ff ff call 1149 <f>
116b: 0f af 45 fc imul eax,DWORD PTR [rbp-0x4]
116f: eb 05 jmp 1176 <f 0x2d>
} else {
return 1;
1171: b8 01 00 00 00 mov eax,0x1
}
}
1176: c9 leave
1177: c3 ret
int main() {
1178: f3 0f 1e fa endbr64
117c: 55 push rbp
117d: 48 89 e5 mov rbp,rsp
1180: 48 83 ec 10 sub rsp,0x10
unsigned int i=5, r=0;
1184: c7 45 f8 05 00 00 00 mov DWORD PTR [rbp-0x8],0x5
118b: c7 45 fc 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0
r = f(i);
1192: 8b 45 f8 mov eax,DWORD PTR [rbp-0x8]
1195: 89 c7 mov edi,eax
1197: e8 ad ff ff ff call 1149 <f>
119c: 89 45 fc mov DWORD PTR [rbp-0x4],eax
uj5u.com熱心網友回復:
研究您的環境的呼叫約定。許多架構的許多呼叫約定的概述:https ://www.dyncall.org/docs/manual/manualse11.html
呼叫約定指定:
其中引數和回傳值必須出現在從呼叫者到被呼叫者的指令流控制轉移的一個單一點上。對于傳遞的引數,該單點是在呼叫之后和被呼叫者的第一條指令之前(對于回傳值,在被呼叫者完成的點和在呼叫者中恢復執行之前)。
許多約定將 CPU 暫存器中的引數傳遞與堆疊記憶體結合起來,用于不適合 CPU 暫存器的引數。甚至一些不使用 CPU 暫存器作為引數的仍然使用 CPU 暫存器作為回傳值。
注冊函式的內容可以破壞而不是必須保留。可以毫無顧慮地為呼叫破壞的暫存器分配新值 可以使用呼叫保留的暫存器,但必須在回傳給呼叫者之前將其恢復到它們在進入時的值。呼叫保留暫存器的優點是,由于它們是由呼叫保留的,因此您可以將它們用于需要在另一個呼叫中存活的變數。
堆疊指標的含義和處理,關于當前指標下方和上方的記憶體,以及堆疊分配的對齊要求。
如果函式以某種方式分配堆疊空間,那么記憶體引數將看起來離堆疊頂部更遠(當然,它們實際上并沒有移動,而是與當前堆疊或幀指標有更大的偏移量)。編譯器知道這一點并相應地調整他們對堆疊記憶體的訪問。
一些編譯器設定幀指標來參考堆疊記憶體。幀指標是在序言中某個點生成的堆疊指標的副本。幀指標并不總是必需的,但有助于例外處理和堆疊展開以及動態堆疊分配。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/484771.html
上一篇:使用同一字典中的鍵擴展dict值
