在函數序言中的當前位置堆棧中保存一個被調用者保存寄存器即使fomit幀指針。
在下面的示例中,sp+4存儲在r7然後在尾聲( LBB0_3 ) 已恢復( r7+4 > r4,r4 > sp ) 。 因此可以跳轉函數,增長堆棧的任何時候在函數內的任意位置而不是把心思花在堆棧上。 如果跳出函數( 通過跳轉*addr ) 則將跳過此尾聲和成為皇室搞砸了堆棧上。
動態的簡短的示例還使用alloca在堆棧上分配內存:
Clang arch Armv7 fomit幀指針c S O0 o 堆棧c#include
int foo(int sz, int jmp) {
char *buf = alloca(sz);
int rval = 0;
if( jmp ) {
rval = 1;
goto done;
}
volatile int s = 2;
rval = s * 5;
done:
return rval;
}
和反彙編代碼:_foo:
@ BB#0:
push {r4, r7, lr}
add r7, sp, #4
sub sp, #20
movs r2, #0
movt r2, #0
str r0, [r7, #-8]
str r1, [r7, #-12]
ldr r0, [r7, #-8]
adds r0, #3
bic r0, r0, #3
mov r1, sp
subs r0, r1, r0
mov sp, r0
str r0, [r7, #-16]
str r2, [r7, #-20]
ldr r0, [r7, #-12]
cmp r0, #0
beq LBB0_2
@ BB#1:
movs r0, #1
movt r0, #0
str r0, [r7, #-20]
b LBB0_3
LBB0_2:
movs r0, #2
movt r0, #0
str r0, [r7, #-24]
ldr r0, [r7, #-24]
movs r1, #5
movt r1, #0
muls r0, r1, r0
str r0, [r7, #-20]
LBB0_3:
ldr r0, [r7, #-20]
subs r4, r7, #4
mov sp, r4
pop {r4, r7, pc}