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個參數,後面的參數放入棧中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章