众所周知,ARM架构下,函数参数是通过 r0~r4寄存器传递的;但是如果参数超过四个,就要借助于栈了。
下面以一个例子说明。
int func(int a1, int a2, int a3, int a4, int a5, int a6) { return a1 + a2 + a3 + a4 + a5; } int main(void) { func(1, 2, 3, 4, 5, 6); return 0; }main()的汇编如下:
0x00010418 <+0>: push {r11, lr} 0x0001041c <+4>: add r11, sp, #4 0x00010420 <+8>: sub sp, sp, #8 0x00010424 <+12>: mov r3, #5 0x00010428 <+16>: str r3, [sp] 0x0001042c <+20>: mov r3, #6 0x00010430 <+24>: str r3, [sp, #4] 0x00010434 <+28>: mov r0, #1 0x00010438 <+32>: mov r1, #2 0x0001043c <+36>: mov r2, #3 0x00010440 <+40>: mov r3, #4 ----> 0x00010444 <+44>: bl 0x103c8 <func> 0x00010448 <+48>: mov r3, #0 0x0001044c <+52>: mov r0, r3 0x00010450 <+56>: sub sp, r11, #4 0x00010454 <+60>: pop {r11, pc}这个时候(执行到箭头指向的位置),栈的状态如下:
函数 func的汇编如下:
0x000103c8 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x000103cc <+4>: add r11, sp, #0 0x000103d0 <+8>: sub sp, sp, #20 0x000103d4 <+12>: str r0, [r11, #-8] 0x000103d8 <+16>: str r1, [r11, #-12] 0x000103dc <+20>: str r2, [r11, #-16] 0x000103e0 <+24>: str r3, [r11, #-20] ; 0xffffffec 0x000103e4 <+28>: ldr r2, [r11, #-8] 0x000103e8 <+32>: ldr r3, [r11, #-12] 0x000103ec <+36>: add r2, r2, r3 0x000103f0 <+40>: ldr r3, [r11, #-16] 0x000103f4 <+44>: add r2, r2, r3 0x000103f8 <+48>: ldr r3, [r11, #-20] ; 0xffffffec ----> 0x000103fc <+52>: add r2, r2, r3 0x00010400 <+56>: ldr r3, [r11, #4] 0x00010404 <+60>: add r3, r2, r3 0x00010408 <+64>: mov r0, r3 0x0001040c <+68>: sub sp, r11, #0 0x00010410 <+72>: pop {r11} ; (ldr r11, [sp], #4) 0x00010414 <+76>: bx lr
ldr r3, [r11, #4]上面这一句汇编代码就是从栈上取回保存的第5个参数的值。
(gdb) x /x $r11 + 4 0xbefffcd0: 0x00000005
原文地址:http://blog.csdn.net/caspiansea/article/details/46114087