汇编(五) -- 函数的参数和返回值

前言

最近准备学习汇编,然后在B站上看到叫iOS小贤的作者发的视频挺不错,打算跟着学,文章是看视频的笔记,最后有原视频链接,想看视频的可以看看通过链接查看视频。

函数的参数和返回值

  • ARM64下,函数的参数通常情况下是存放在X0到X7(W0到W7)这8个寄存器里面的。如果超过8个参数,就会入栈。
  • 编译器决定的函数的返回值通常都是放在x0中,之所以是通常是因为比如返回值是一个结构体,x0只能放64位即8个字节,这个时候放不下。

我们新写一个sum方法,然后打断点

Screen Shot 2019-08-09 at 2.32.44 PM.png
mov    w0, #0xa
mov    w1, #0x14

这两句是把#0xa(10),#0x14(放入)w0(x0的低32位)和w1(x1的低32位)中。接下来bl 0x10273a94c就进入sum函数。

Screen Shot 2019-08-09 at 2.43.31 PM.png
sub    sp, sp, #0x10 

拉伸栈空间#0x10(16位)。

str    w0, [sp, #0xc]
str    w1, [sp, #0x8]

w0和w1的值放入了栈空间,位置是sp偏移#0xc,sp偏移#0x8。

ldr    w0, [sp, #0xc]
ldr    w1, [sp, #0x8]

把栈空间的值读出来放入寄存器w0,w1。看起来有点滑稽,但是在打包的时候编译器会做优化。

add    w0, w0, w1

w0和w1的值相加然后放入w0。

add    sp, sp, #0x10 
ret

栈平衡并且return。

用汇编手写求和函数

在函数内部没有调用其他函数的函数叫做叶子函数。

叶子函数没有必要开辟栈空间,不移动sp的位置,直接通过sp的偏移,放入sp开始的低地址的区域中,因为接下来不会调用别的函数,就不会有其他函数干扰,所以没问题。而且调用完毕之后这块区域也不需要了,别的函数在用的时候,sp往低地址移动,开辟新的栈空间栈空间会先写再读,所以不会有影响。

Screen Shot 2019-08-09 at 3.09.33 PM.png

这样我们可以写出精简版的sum函数的汇编代码

.text
.global _suma

_suma:
    add x0, x0 , x1
    ret
Screen Shot 2019-08-09 at 8.29.17 PM.png

我们看到输出了正确结果30。

有人可能会问为何结果放入x0中,这是由编译器的,我们试试看放入x1会怎样,结果输出了10。这是因为把结果放入x1,而x0仍然第一个参数是10。


Screen Shot 2019-08-09 at 8.30.28 PM.png

函数参数超过8个

Screen Shot 2019-08-09 at 8.43.40 PM.png
sub    sp, sp, #0x30

sp向低地址拉伸16*3=48个字节,如下图

Screen Shot 2019-08-09 at 8.50.25 PM.png
Screen Shot 2019-08-09 at 8.51.09 PM.png
stp    x29, x30, [sp, #0x20]

sp偏移#0x20即向高地址出偏移2*16=32个字节,然后写入x29和x30,前面讲过读写是往高地址,于是之后的内存布局如下图:

Screen Shot 2019-08-09 at 8.59.17 PM.png
add    x29, sp, #0x20

sp加#0x20其实和上面[sp, #0x20]一样,然后赋值给x29。


Screen Shot 2019-08-09 at 9.04.24 PM.png
stur   wzr, [x29, #-0x4]
stur   w0, [x29, #-0x8]
str    x1, [sp, #0x10]

执行这几个命令之后内存图如下:

Screen Shot 2019-08-09 at 9.27.24 PM.png
orr    w0, wzr, #0x1
orr    w1, wzr, #0x2
orr    w2, wzr, #0x3
orr    w3, wzr, #0x4
mov    w4, #0x5
orr    w5, wzr, #0x6
orr    w6, wzr, #0x7
orr    w7, wzr, #0x8
mov    w8, #0x9

orr是或得意思,前面讲过ARM64中

  • 64位: X0-X30, XZR(零寄存器)
  • 32位: W0-W30, WZR(零寄存器)

所以是#0x1和0进行或运算,然后赋值给w0,相当于mov w0, #0x1

w8, [sp]

因为函数的参数通常情况下是存放在X0到X7(W0到W7)这8个寄存器里面的,所以w8不能参数,于是直接把w8放入栈中,也就是#0x9,就是参数9。

Screen Shot 2019-08-09 at 10.06.53 PM.png

在调用sum函数bl 0x1050028bc ; sum1 at main.m:16之前,对栈的操作就是这么个过程。
总结:

  1. 就是拉伸了栈空间
  2. 然后往栈中保护了两个寄存器x29,x30
  3. 接下来保护w0和x1寄存器
  4. 然后把参数放入w1到w7
  5. 最后多出来参数放入栈空间

然后进入sum函数

Screen Shot 2019-08-09 at 9.43.19 PM.png
sub    sp, sp, #0x30 

又是拉伸栈空间,拉升了#0x30。

Screen Shot 2019-08-09 at 9.51.45 PM.png
ldr    w8, [sp, #0x30]

[sp, #0x30]是sp加上#0x30,就是刚刚sp的位置,然后向高地址处读取值放入w8中,就是刚刚放的参数,这里读出放入栈中的参数。

str    w0, [sp, #0x2c]
str    w1, [sp, #0x28]
str    w2, [sp, #0x24]
str    w3, [sp, #0x20]
str    w4, [sp, #0x1c]
str    w5, [sp, #0x18]
str    w6, [sp, #0x14]
str    w7, [sp, #0x10]

把w0到w7里的参数入栈。

ldr    w0, [sp, #0x2c]
ldr    w1, [sp, #0x28]
add    w0, w0, w1

从栈中取出来,两两相加。

ldr    w1, [sp, #0x24]
add    w0, w0, w1
ldr    w1, [sp, #0x20]
add    w0, w0, w1
ldr    w1, [sp, #0x1c]
add    w0, w0, w1
ldr    w1, [sp, #0x18]
add    w0, w0, w1
ldr    w1, [sp, #0x14]
add    w0, w0, w1
ldr    w1, [sp, #0x10]
add    w0, w0, w1
ldr    w1, [sp, #0x30]
add    w0, w0, w1

参考

函数的参数和返回值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容