call & stack
stack有兩個動作,push放入堆疊,pop取出
push raxrsp暫存器永遠指著堆疊頂部

- 將rsp減少
- 將內容從新的rsp開始放入
類似代碼:
sub rsp, 8mov [rsp], rax在C/C++的編譯風格,每次進入函數開始前會像上圖一樣分配一塊適當大小的空間
rbp指向區域變數的頂端
先 push rbp 將原先的rbp保存起來,然後把rbp設為當前rsp,再把rsp減去要分配的空間大小
以上圖來說明就是 rbp = rsp, rsp -= 0x8
在函數結束的最後做相反的動作把rsp加回來再 pop rbp 還原rbp成上一個地方的區域變數頂端位址
自己編寫assembly不一定要使用C/C++的區域變數風格
pop rbx
pop的動作跟push相反
- 將rsp內容取出
- 將rsp增加
類似代碼:
mov [rsp], rbxadd rsp, 8使用 call label 呼叫函數,和 jmp label 非常相似,差別是call結束會返回原本的下一行
call前我們需要手動將參數依序放入固定位置,rdi, rsi, rdx, rcx, r8, r9, push… 然後使用call
指令call可以拆分成以下兩個動作
push ripjmp label將永遠指向下一行指令位址的rip推入堆疊,然後jmp
接著執行完內容使用ret返回到原本的下一行繼續執行,若有返回值請手動存入rax再做ret
ret一樣可以拆分為下列動作
pop rip將之前的rip從堆疊取出並放入rip,程式會依照rip所指的地方執行