代码改变世界

iOS安全攻防(十三)arm汇编之函数(int参数)传递

2014-12-14 19:56  16字节  阅读(1404)  评论(0编辑  收藏  举报

个人原创,转帖请注明来源:cnblogs.com/jailbreaker

之前讲到函数调用的参数传递通过r0-r3来实现,这篇帖子我们来验证下。先看一个4个参数的函数代码:

NewImage

main方法简单调用compute方法,先看main的汇编代码:

NewImage

明显可以看出,参数值1,2,3,4分别传递给r0-r3,然后通过b调用函数 compute,接着看下compute的汇编代码:

NewImage

最后一行 是返回到 调用者的下一行,之前帖子已经学过了,前面面3条代注释如下:

add r0, r1     //r0 = r0+r1

add r0,r2     //r0 = r0+r2

subs r0,r0,r3     //r0 = r0 - r3 

比较下汇编代码和源代码,就能理解r0-r3的功能,这里的被调用函数是4个参数,正好对应r0-r3  4个寄存器,如果参数是多个,又会怎么样,修改源代码如下:

NewImage

还是看main汇编代码:

NewImage

目前汇编的main方法 和之前的版本差异还是比较大的,行数36 - 38 ,这里可以看出开创了一个新的栈帧,而大小是12个字节,其实就是函数最后3个参数需要保存的位置,行数50 - 51,做的是针对36 - 38 开创空间的清理工作。

行数39 - 41,把实参5,7,6赋予r2,r0和r1,这里顺序其实无所谓了,因为者3个寄存器作为临时保存,后面42,43,45行的功能将这个值分别保存到[sp+0],[sp+4],[sp+8]内存位置,剩余的mov代码都能看懂了,之后调用compute,再来看下compute内部的汇编代码:

NewImage

重点看下 20 ,22,24行 ldr 指令,ldr lr,[r7,#8] 的含义是将r7+8地址上的值 保存到lr里,这里为啥是+8,而不是+0,因为在16行,先后push了lr和r7(27行pop出来),正好是8字节,所以r7+8就是前面栈帧分配的参数。