C IN ARM64 汇编基础-函数和程序结构-基于The C Programming Language - Second Edition

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个参数,后面的参数放入栈中。

猜你喜欢

转载自blog.csdn.net/EMH1899/article/details/83151967