C源码:
#include <stdio.h>
int add(int a, int b) {
return a+b;
}
汇编源码:
0000000000000558 <add>:
558: d10043ff sub sp, sp, #0x10 //申请16个bytes
55c: b9000fe0 str w0, [sp,#12] //w0的内容放入sp+12
560: b9000be1 str w1, [sp,#8] //w1的内容放入sp+8
564: b9400fe0 ldr w0, [sp,#12] //取sp+12的值放入w0
568: b9400be1 ldr w1, [sp,#8] //取sp+8的值放入w1
56c: 0b010000 add w0, w0, w1 //w0 = w0 + w1
570: 910043ff add sp, sp, #0x10 //释放栈空间
574: d65f03c0 ret
从上面的汇编可以看出分别使用x0和x1寄存器存储第1个和第2个参数,寄存器x0存储函数的返回值
写一个函数来调用add函数,看看实际情况:
C源码:
#include <stdio.h>
int add(int a, int b) {
return a+b;
}
int main(int argc, const char *argv[]) {
return add(1,2) + 1;
}
对应的汇编代码:
00000000000005c8 <main>:
5c8: d10083ff sub sp, sp, #0x20
5cc: a9017bfd stp x29, x30, [sp,#16]
5d0: 910043fd add x29, sp, #0x10
5d4: 320003e8 orr w8, wzr, #0x1
5d8: 321f03e9 orr w9, wzr, #0x2
5dc: b81fc3bf stur wzr, [x29,#-4]
5e0: b9000be0 str w0, [sp,#8]
5e4: f90003e1 str x1, [sp]
5e8: 2a0803e0 mov w0, w8 //w0存储第一个参数1
5ec: 2a0903e1 mov w1, w9 //w1存储第二个参数2
5f0: 97ffffbe bl 4e8 <add@plt>
5f4: 11000400 add w0, w0, #0x1 //add函数的返回值放入寄存器w0,继续+1
5f8: a9417bfd ldp x29, x30, [sp,#16]
5fc: 910083ff add sp, sp, #0x20
600: d65f03c0 ret
main在调用到add函数之前会把参数放入x0和x1,add函数使用x0作为返回值,然后main继续+1
如果有更多的参数,传递方式是怎样的呢?
C源代码:
#include <stdio.h>
int add(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,int k,int l) {
return a+b+c+d+e+f+g+h+i+j+k+l;
}
int main(int argc, const char *argv[]) {
return add(1,2,3,4,5,6,7,8,9,10,11,12);
}
汇编源代码:
0000000000000658 <main>:
658: d10103ff sub sp, sp, #0x40
65c: a9037bfd stp x29, x30, [sp,#48]
660: 9100c3fd add x29, sp, #0x30
664: 320003e8 orr w8, wzr, #0x1
668: 321f03e9 orr w9, wzr, #0x2
66c: 320007e2 orr w2, wzr, #0x3
670: 321e03e3 orr w3, wzr, #0x4
674: 528000a4 mov w4, #0x5 // #5
678: 321f07e5 orr w5, wzr, #0x6
67c: 32000be6 orr w6, wzr, #0x7
680: 321d03e7 orr w7, wzr, #0x8
684: 5280012a mov w10, #0x9 // #9
688: 5280014b mov w11, #0xa // #10
68c: 5280016c mov w12, #0xb // #11
690: 321e07ed orr w13, wzr, #0xc
694: b81fc3bf stur wzr, [x29,#-4]
698: b81f83a0 stur w0, [x29,#-8]
69c: f81f03a1 stur x1, [x29,#-16]
6a0: 2a0803e0 mov w0, w8
6a4: 2a0903e1 mov w1, w9
6a8: b90003ea str w10, [sp]
6ac: b9000beb str w11, [sp,#8]
6b0: b90013ec str w12, [sp,#16]
6b4: b9001bed str w13, [sp,#24]
6b8: 97ffff8e bl 4f0 <add@plt>
6bc: a9437bfd ldp x29, x30, [sp,#48]
6c0: 910103ff add sp, sp, #0x40
6c4: d65f03c0 ret
参数3、4 、5 、6 、7 、8 、9 、a 、b 、c先放入寄存器w2-w13,参数1 、2分别放入寄存器w8、w9,然后w8、w9会放入w0、w1,w10、w11、w12、w13依次放入栈sp、sp+8、sp+16、sp+24的位置。也就是x0-x7放前8个参数,后面的参数放入栈中。