2017年11月7日 星期二

[C] stack frame and frame pointer

定義:
stack frame(堆疊框架): 一個函式所包含的堆疊區塊
frame pointer:用來界定 stace frame 位置(的暫存器

目的:
可利用frame pointer與相對定址存取函式中的變數與參數

實驗:
使用online compilerhttps://gcc.godbolt.org/ ),
翻譯成組語,來查看frame pointer的操作


C:
void caller(void){
int a, b, c;
a=99;
b=123;

c = add(a, b);
}

int add(int a, int b){
int c[1];
c[0] = a;
    return c[0] + b;
}

assembly:
caller():
----------------------------------------------------------------------------- prologue
Audio $sp, $sp, -48 #expand stack
sw $31,44($sp) #push ra
sw $fp,40($sp) #push fp (fp代表函式開頭時的堆疊)
move $fp,$sp # fp = ra
----------------------------------------------------------------------------- body
li $2,99 # 0x63
sw $2,24($fp) #利用fp及相對定址將a存到stack中(sp已經指到後面了,用起來不方便)
li $2,123
sw $2,28($fp)
lw $5,28($fp)
lw $4,24($fp) #add的參數(為副本), 放在堆疊上
jal add(int, int) #呼叫add()
nop
---------------------------------------------------------------------------- eplilogue(動作與prologue相反)
sw $2,32($fp)
nop
move $sp,$fp #回復 sp
lw $31,44($sp) #回復ra
lw $fp,40($sp) #回復fp
addiu $sp,$sp,48 #回復sp
j $31 #return
nop

add(int, int):
addiu $sp,$sp,-24 #expand stack
sw $fp,20($sp) #push fp
move $fp,$sp #fp = ra
sw $4,24($fp) #參數 b(利用fp存取caller的參數)
sw $5,28($fp) #參數 a
lw $2,24($fp)
nop
sw $2,8($fp)
lw $3,8($fp)
lw $2,28($fp)
nop
addu $2,$3,$2
move $sp,$fp
lw $fp,20($sp)
addiu $sp,$sp,24
j $31
nop

重點:
1. frame pointer的作用
2. prologue 與 eplilogue的動作包含:  rafp, sp的處理

reference:

沒有留言:

張貼留言