Stack Frame
3λ κ° μ°μ κΈ°λ₯μμμΌλ‘ 볡무 νκ³ , 볡νν΄ μ»΄κ³΅κ³Ό μμ μ λ£κ³ μμ΅λλ€. κ·Έλμ λ§μ΄ λ°°μ λ€κ³ μκ°νλλ°, μ¬μ ν λΆμ‘±ν λΆλΆμ΄ λ§λ€μ ^^;; μμ μΈμλ λκ³ κ³΅λΆμ κΈΈλ λμ κ² κ°μ΅λλ€.
λ€μ΄κ°λ©°
λΆλͺ βλ§μ΄ν¬λ‘ νλ‘μΈμβ μμ λ μ΄μ λΈλ¦¬λ₯Ό νλ©΄μ λ°°μ λ κ² κ°μλ°, ꡰ볡무λ₯Ό νκ³ μ€λκΉ λ€ κΉλ¨Ήμλ€ γ γ μ΄μ체μ μμ μ λ€μΌλ©΄μ μ΄ λΆλΆμ λ€μ λ³΄κ² λ μΌμ΄ μκ²Όλλ°, μ μ€λͺ ν μλ£λ μμ§λ§ λ΄ μ λ§μ λ§κ² μ΄λ¦¬μ 리 μ‘°μ ν΄ κΈλ‘ μ 리ν΄λ³Έλ€ γ γ
μ, 미리 λ§ν΄λμ§λ§ CμΈμ΄μ x86-gcc
μ»΄νμΌλ¬λ₯Ό κΈ°μ€μΌλ‘ μ€λͺ
νλ€. κ·Έλ¦¬κ³ μ¬κΈ°μ μ€λͺ
νλ push
, pop
κ°μ λͺ
λ Ήμ΄λ assembly λͺ
λ Ήμ΄λ₯Ό μλ―Ένλ©°, x86-gcc
μμ μ¬μ©νλ CISC λͺ
λ Ήμ΄μ
μ λ°λ₯Έλ€. μ΄μ
λΈλ¦¬ λ¬Έλ²μ βIntel λ¬Έλ²βμ λ°λμλ λ°νλ€.
Stackframeμ΄λ??
μΌλ¨ Stackframe μ체λ μ€ν λ©λͺ¨λ¦¬μ μ‘΄μ¬νλ κ³΅κ° μ€ μΌλΆμ΄λ€. ν¨μμ½μ΄ λ°μν λ, κ·Έ ν¨μμ life cycle λμ μ¬μ©νλ μ€ν λ©λͺ¨λ¦¬ 곡κ°μΈλ°, μ¬κΈ°μ ν¨μμ μΈμ(args)μ κ°μ’ μ§μλ³μμ μ€κ° μ°μ° κ²°κ³Όλ€μ΄ μ μ₯λλ€.
μ€ν λ©λͺ¨λ¦¬μμ ν¨μμ½κ³Ό κ΄λ ¨λ λΆλΆμ΄κΈ° λλ¬Έμ βcall stackβλΌκ³ λΆλ₯΄κΈ°λ νλ€.
Registers
μ€ν νλ μμ΄ λμνλ κ³Όμ μμ μ¬μ©νλ λ μ§μ€ν°λ€λΆν° μ΄ν΄λ³΄μ. μΌλ¨ μ΄λ¦λ§ κ°λ¨ν μ΄ν΄λ³Έλ€.
Overview
Stack Frameμ μ΄ν΄λ₯Ό λκΈ° μν΄ βμμ£Ό λ§μ΄β μΆμνλ λ²μ μ λλ€.
- Stack Pointer; SP
- μ€νμ κ°μ₯ μλ(lowest)μ μ£Όμκ°μ κ°λ¦¬ν€λ λ μ§μ€ν°μ΄λ€.
- λμΆ© current, latest μμΉλ₯Ό κ°λ¦¬ν€λ λ μ§μ€ν°μ΄λ€.
push
λͺ λ Ήμ΄λ₯Ό μννλ©΄, SP κ°μ΄ κ°μνλ€. (μ€νμ μμμ μλλ‘ μλΌλκΉ!): SP - 4pop
λͺ λ Ήμ΄λ₯Ό μννλ©΄, SP κ°μ΄ μ¦κ°νλ€. SP + 4- ν¨μ μ’
λ£λ λ, μ€ν λ©λͺ¨λ¦¬λ₯Ό μ 리νλλ°λ μ¬μ©νλ€.
- μ λΆλΆμ λ€μμ ν¨μκ° μ’ λ£λλ μν©μ μκΈ°ν λ λ€λ£¬λ€.
- Base Pointer; BP
- μ€ν νλ μμ μμ μμΉλ₯Ό κ°λ¦¬ν€λ λ μ§μ€ν°μ΄λ€.
- ν¨μκ° μ€νλλ λμ BPλ κ·Έ νλ μμ μμ μμΉμ κ³ μ λμ΄ κ·Έ κ°μ΄ λ³νμ§ μλλ€.
- ν¨μ λ΄μ λ§€κ° λ³μλ₯Ό μ°Έμ‘°ν λ, κΈ°μ€μ μΌλ‘ μ¬μ©νλ€.
- μ λΆλΆλ λ€μμ 맀κ°λ³μμ λν΄ μκΈ°ν λ λ€λ£¬λ€.
- ν¨μ λ΄μ μ§μ λ³μλ₯Ό μ°Έμ‘°ν λ, κΈ°μ€μ μΌλ‘ μ¬μ©νλ€.
- μκ²λ λ€μμ μ§μλ³μμ λν΄ μλΌν λ λ€λ£¬λ€.
- Link Pointer; LP λλ Index Pointer; IP
- ν¨μ νΈμΆμ΄ μ’ λ£λ ν 볡κ·ν μ½λ μ£Όμλ₯Ό λ΄λ λ μ§μ€ν°
- ν¨μ νΈμΆμ΄ λ°μνλ©΄, κ·Έ μ§μ μ μ½λ μ£Όμλ₯Ό LPμ μ μ₯νλ€.
- ν¨μκ° μ’
λ£λλ©΄, LPμ μ μ₯λ μ½λ μ£Όμλ‘ μ΄λνλ€. (
jmp lp
) - μ²μ 보면 ν·κ°λ¦΄ μλ μλλ°, LPκ° λ΄λ μ£Όμκ°μ μ€ν μμμ΄ μλλΌ μ½λ μμμ΄λ€!!
μ¬μ©λλ μλ리μ€
ν¨μκ° νΈμΆλκ³ , λ¦¬ν΄ λλ κ³Όμ μμ μμ λ μ§μ€ν°λ€μ΄ μ΄λ»κ² λμνλμ§ μ΄ν΄λ΄ μλ€. μμ κ·Έλ¦Όκ³Ό ν¨κ» κ³Όμ μ λ°λΌκ°λ΄ μλ€. (Intel λ¬Έλ²μ κΈ°μ€μΌλ‘ μμ± λμ΄ μμ΅λλ€.)
- ν¨μ νΈμΆ μ§μ (caller saves)
- νΈμΆ ν¨μλ ν¨μμ μΈμ argsκ° μ€νμ μ μ₯ν¨. (
push 100
) - ν¨μλ₯Ό νΈμΆν μ§μ μ μ½λ μ£Όμλ₯Ό μ€νμ μ μ₯ν¨.
- νΈμΆ ν¨μλ ν¨μμ μΈμ argsκ° μ€νμ μ μ₯ν¨. (
- ν¨μ μ€ν μ§μ
- μ΄μ ν¨μμ BP κ°μ μ€νμ μ μ₯ν¨. (
push rbp
) - κ·Έλ¦¬κ³ BP κ°μ νμ¬μ SP κ°μΌλ‘ μ
λν¨. (
mov rbp, rsp
) - ν¨μμ λ‘컬 λ³μλ€μ ν보ν¨. (
sub rsp, N
)
- μ΄μ ν¨μμ BP κ°μ μ€νμ μ μ₯ν¨. (
- ν¨μ μ€ν μ€
- BP κ°μ ν¨μκ° μ€νλλ λμ μ€ν νλ μμ μμ μμΉλ₯Ό κ°λ¦¬ν€λ©° κ³ μ λ¨.
- SPλ νμ¬ μ€νμ μμΉλ₯Ό λνλ. λ³μκ°μ μ€νμ μ μ₯νκ±°λ(
push
), μ€νμμ λΉΌμ€λ©΄(pop
), κ·Έ κ°μ΄ μ€μ΄λ€κ±°λ λμ΄λ¨.
- ν¨μ μ’
λ£ μ
- SPλ₯Ό μ μ₯ν΄λ BP μμΉλ‘ μ΄λμν΄. (
mov rsp, rbp
) - μ€νμ μ μ₯ν΄λλ caller ν¨μμ BPλ₯Ό 볡ꡬν¨. (
pop rbp
) - μ€νμ μ μ₯ν΄λλ λ³΅κ· μ£Όμλ₯Ό μ¬μ©ν΄ μ½λ μ£Όμλ‘ λ³΅κ·ν¨.
- SPλ₯Ό μ μ₯ν΄λ BP μμΉλ‘ μ΄λμν΄. (
Access Stack
Allocate stack space for local vars
μμ κ³Όμ μ€μ 2.3 λ¨κ³μμ μΌμ΄λλ ν¨μμ λ‘컬 λ³μλ₯Ό ν보νλ κ³Όμ μ μ’λ μ΄ν΄λ³΄μ.
// example to understand function's local variables
void square(int n) {
int a;
double b;
int arr[100];
// more complex code
for (int i=0; i < 10; i++) {
printf("%d", i);
}
return n * n;
}
λ³ΈμΈμ΄ Stack Frameμ μ²μ μμκ°λ©΄μ μ΄ν΄κ° μ λμλ λΆλΆμ βλ‘컬 λ³μλ₯Ό ν보ν 곡κ°μ΄ μΌλ§μΈ μ€ μκ³ , sub rsp, N
λ₯Ό νλ κ±°μ§?βλΌλ μκ°μ΄μλ€. λ‘컬 λ³μλ μ½λλ₯Ό μ§λ κ³Όμ μμ μ΄λ€ κ³³μμλ μ§ λ±μ₯ν μ μλ€. μμ μ½λμ²λΌ ν¨μμ μ²μμ μ¬μ©νλ λ‘컬 λ³μλ€μ μ μνκ³ μμν μλ μκ³ , μ½λλ₯Ό μ§λ κ³Όμ μμ (for int i=0; ...)
μ²λΌ μμ°μ€λ½κ² μ μΈλλ κ²½μ°λ μλ€.
μ΄λ¦¬μ 리 μ°Ύμ보λ sub rsp, N
λμμμ μ°λ N
μ μ»΄νμΌ νμ
μ κ²°μ λλ€κ³ νλ€! μ»΄νμΌλ¬κ° μ½λλ₯Ό μ μ μΌλ‘ λΆμνμ¬ ν¨μμμ μ°λ λ‘컬 λ³μλ€μ μ λΆ λͺ¨μλ€. κ·Έλ¦¬κ³ κ·Έκ²λ€μ κ° λ³μ νμ
μ λ§μΆ°μ int
λ³ 4λ°μ΄νΈ, double
μ΄λ©΄ 8λ°μ΄νΈ, int arr[100]
μ΄λ©΄ 400 λ°μ΄νΈβ¦ μ΄λ° μμΌλ‘ λ‘컬 λ³μμ κ°μ΄ μ μ₯λκΈ° μν κ°μ κ³μ°ν΄μ N
κ°μ ꡬνλ€κ³ νλ€.
Access Args and Local vars
Base Pointerλ μ¬λ°λ νΉμ±μ κ°μ§κ³ μλλ°, BP κΈ°μ€μΌλ‘ μμλ Nκ°μ ν¨μ argsκ° μμΉνκ³ , μλλ Mκ°μ λ‘컬 λ³μκ° μ€ν κ³΅κ° μμ μ‘΄μ¬νλ€. κ·Έλμ ν¨μ μ½λμμ ν¨μ argsλ λ‘컬 λ³μμ μ κ·Όνλ €λ©΄, BPλ₯Ό κΈ°μ€μΌλ‘ mov eax, [bp + 8]
νκ±°λ mov ebx, [bp - 4]
ν΄μ μ κ·Όνλ€.
κ·Έλ°λ° μ¬κΈ°μ κΆκΈμ¦μ΄ μ긴건, βμ΄μ
λΈλ¦¬ μ½λλ κ° λ‘컬 λ³μκ° BP κΈ°μ€μΌλ‘ λͺ offset λ§νΌ λ¨μ΄μ Έ μλμ§λ₯Ό μ΄λ»κ² μκ³ [bp - 4]
λΌκ³ μ°μ΄μ£Όλ κ±°μ§?βλΌλ μκ°μ΄ λ€μλ€.
μ΄κ²λ μ΄λ¦¬μ 리 μ°Ύμ보λ, μ λ΅μ μ»΄νμΌ νμμ μμλ€ γ γ μ»΄νμΌλ¬λ κ° μ§μ° λ³μλ€μ΄ BP κΈ°μ€ μΌλ§νΌ λ¨μ΄μ§ 곡κ°μ μμΉνλμ§ κ·Έ offset μ 보λ₯Ό λ΄μμ κ΄λ¦¬νλ€. μ΄λ₯Ό Offset Table λλ Symbol TableλΌκ³ νλ€.
μ»΄νμΌλ¬λ C μ½λλ₯Ό μ΄μ
λΈλ¦¬κ³ λ°κΏλ, κ° λ‘컬 λ³μλ€μ [bp - ??]
λ‘ μΉννλ€. ??
κ°μ μμμ μΈκΈν Offset Tableμ μν΄ κ²°μ λλ€.
ν¨μ μ’ λ£μ μμ
ν¨μκ° μ’ λ£λ λμ λμ
μΌλ¨ SPλ₯Ό μλ μμΉλ‘ 볡μν΄μΌ νλ€. μ΄κ²μ μλ μ΄μ λΈλ¦¬ λͺ λ Ήμ΄λ‘ μνν μ μλ€.
mov sp, bp ; BP κ°μ SPλ‘ λ³΅μ¬ν΄ μ€νμ μ 리
μ΄μ BP κ°μ callerμ BP κ°μΌλ‘ 볡μνλ€. μ΄κ²λ μλμ λͺ λ Ήμ΄λ‘ μνν μ μλ€.
pop bp
μμ κ³Όμ μ ν΅ν΄ BPκ° κ°λ¦¬ν€λ κ³³μ μ μ₯λμ΄ μλ caller BP κ°μ΄ BP λ μ§μ€ν°μ μ μ₯λλ€. pop
μ΄ νΈμΆλμκΈ° λλ¬Έμ, SPλ μλμΌλ‘ SP += 4 μ²λ¦¬ λλ€ γ
γ
μ΄μ
λΈλ¦¬μμλ μ mov
μ pop
κ³Όμ μ ν©μ³μ leave
λΌλ λͺ
λ Ήμ΄λ‘ μ 곡νκΈ°λ νλ€.
μ΄μ μ€νμ μ μ₯νλ return_addr
λ₯Ό LP λ μ§μ€ν°μ λ£μ΄μ ν¨μ νΈμΆμ΄ μ’
λ£λ λ, callerμ μ½λ μ£Όμλ‘ μ΄λν΄μΌ νλ€. μ΄κ²μ ret
λͺ
λ Ήμ΄λ‘ μνν μ μλ€!
ret
λͺ
λ Ήμ΄λ₯Ό μ’λ νμ΄ μ°λ©΄, μλμ κ°μ κ²μ΄λ€.
pop lp
jmp lp
μ¦, pop
νκ³ jmp
νλ κ³Όμ μ λ¬Άμ΄μ€κ² ret
μΈ μ
!!
μ΄νμ Caller μͺ½μμ ν λΉνλ argsλ₯Ό pop
ν΄μ£Όλ κ³Όμ λ νμνλ°, μλμ ν¨μ νΈμΆ ν λμ λμκ³Ό κ°μ΄ μ΄ν΄λ³΄μ γ
γ
ν¨μλ₯Ό νΈμΆν λμ λμ
ν¨μλ₯Ό νΈμΆν λ Stack Frame μΈν μ μν΄ μΌλ ¨μ μ΄μ λΈλ¦¬ λͺ λ Ήμ΄λ€μ΄ νΈμΆλλλ°, Callerκ° μννλ λΆλΆκ³Ό Calleeκ° μννλ λΆλΆμΌλ‘ λλλ€.
; Caller Part
push 100
call square(int)
; Callee Part
push bp
mov bp, sp
sub sp, N
- ν¨μκ° νΈμΆ λκΈ° μ μ Callerμμ ν¨μμ μ λ¬λλ argsλ₯Ό μ€νμ
push
νλ€. call
λ‘ ν¨μ μ½λλ‘ μ΄λνλ€.- μ΄λ,
call
λͺ λ Ήμ΄μ μ½λ μ£Όμλ₯Ό stack frameμ μ μ₯νλpush lp
κ³Όμ λ ν¨κ» μνλλ€. - μ¦,
call
λͺ λ Ήμ΄κ°push lp; jmp square
μΈ μ .
- μ΄λ,
- μ¬κΈ°μλΆν° Calleeμ μ΄μ λΈλ¦¬ λΈλ‘μμ μ€νλλ ννΈλ€.
push bp
λ‘ μ΄μ stack frameμ BPλ₯Ό μ€νμ μ μ₯νλ€.mov bp, sp
λ‘ BPμ κ°μ νμ¬ stack frameμ μν κ²μΌλ‘ κ΅μ²΄νλ€.sub sp, N
μΌλ‘ μ§μ λ³μλ₯Ό ν λΉνλ€.
ν¨μ Termination ννΈκΉμ§ ν΄μ κ°μ΄ 보면 μλμ κ°λ€.
; Caller Initialize Part
push 100
call square(int)
; Callee Initialize Part
push bp
mov bp, sp
sub sp, N
; Callee do something...
...
; Callee Termination
leave
ret
; Caller Termination (remove args)
pop
ret
μ μ€νν΄μ Callerλ ν¨μ νΈμΆμμ λμμ¨ νμλ, pop
μΌλ‘ μ€νμ λ£μ΄λλ ν¨μ argsλ₯Ό λΉΌμ£Όλ κ³Όμ μ΄ μΌμ΄λλ€!
ν¨μ 리ν΄κ°μ eax λ μ§μ€ν°μ μ μ₯λλ€.
λ§μ½ ν¨μμ 리ν΄κ°μ΄ μ‘΄μ¬νλ€λ©΄, κ·Έ κ°μ eax
λ μ§μ€ν°μ μ μ₯λλ€.
; Callee Termination
mov eax, 42
leave
ret
; Caller Termination (remove args)
pop
ν¨μκ° ret
μΌλ‘ μ’
λ£λκΈ° μ μ mov eax, xxx
λ₯Ό ν΅ν΄ eax
λ μ§μ€ν°μ λ΄κΈ΄λ€. κ·Έλ¬λ©΄ μ½λ¬ ν¨μλ eax
μ μ μ₯λ λ¦¬ν΄ κ°μ μ¬μ©νκ±°λ, μ½λ¬ ν¨μμ μ€νμ μ΄λ€ λ³μλ‘ μ μ₯νλ€.
λ¦¬ν΄ κ°μ λ€λ₯Έ λ μ§μ€ν°κ° μλλΌ νμ eax
μ μ μ₯λλλ°, μ΄κ²μ x86 μν€ν
μ²μμ βCalling Conventionβμ΄κΈ° λλ¬Έμ΄λ€. ν΄λΉ κ·μ½μμλ ν¨μ λ¦¬ν΄ κ°μ eax
λ μ§μ€ν°μ λ΄λλ‘ μ μνκ³ μλ€. μ¬μ€ eax
λ μ§μ€ν°λ βλμ°κΈ°(Accumulator) λ μ§μ€ν°βλΌλ μ΄λ¦μΌλ‘, μ°μ μ°μ°μ κ²°κ³Όλ₯Ό λ΄κΈ° μν΄ λμμΈλ λ μ§μ€ν°μ΄μ§λ§, μ ν¨μ λ¦¬ν΄ κ°μ μ μ₯νλ μ©λλ‘λ μ¬μ©λλ κ²μ΄λ€.
Overall ASM Code
square(int):
push bp
mov bp, sp
; Do multiplication
leave
ret
main:
push bp
mov bp, sp
push 100
call square(int)
pop