对于ARM32架构,函数调用时前4个参数用通用寄存器(R0~3),剩余的用栈。对于ARM64架构,函数调用时前8个参数用通用寄存器(R0~7),剩余的通过栈。
测试程序:
1 #include <stdio.h> 2 3 int func(int a, int b, int c, int *e, int f, int *g, int h, int i, int j, int *k) 4 { 5 6 return a+b+c+*e+f+*g+h+i+j+*k; 7 } 8 9 int main(int argc, const char *argv[]) 10 { 11 int e = 4, g=6, k=10; 12 13 printf("%d\n", func(1, 2, 3, &e, 5, &g, 7, 8, 9, &k)); 14 15 return 0; 16 }
对应的汇编(-S):
ARM32:
1 .arch armv7-a 2 .eabi_attribute 28, 1 3 .eabi_attribute 20, 1 4 .eabi_attribute 21, 1 5 .eabi_attribute 23, 3 6 .eabi_attribute 24, 1 7 .eabi_attribute 25, 1 8 .eabi_attribute 26, 2 9 .eabi_attribute 30, 6 10 .eabi_attribute 34, 1 11 .eabi_attribute 18, 4 12 .file "a.c" 13 .text 14 .align 1 15 .global func 16 .syntax unified 17 .thumb 18 .thumb_func 19 .fpu vfpv3-d16 20 .type func, %function 21 func: 22 @ args = 24, pretend = 0, frame = 16 23 @ frame_needed = 1, uses_anonymous_args = 0 24 @ link register save eliminated. 25 push {r7} 26 sub sp, sp, #20 27 add r7, sp, #0 28 str r0, [r7, #12] 29 str r1, [r7, #8] 30 str r2, [r7, #4] 31 str r3, [r7] 32 ldr r2, [r7, #12] 33 ldr r3, [r7, #8] 34 add r2, r2, r3 35 ldr r3, [r7, #4] 36 add r2, r2, r3 37 ldr r3, [r7] 38 ldr r3, [r3] 39 add r2, r2, r3 40 ldr r3, [r7, #24] 41 add r2, r2, r3 42 ldr r3, [r7, #28] 43 ldr r3, [r3] 44 add r2, r2, r3 45 ldr r3, [r7, #32] 46 add r2, r2, r3 47 ldr r3, [r7, #36] 48 add r2, r2, r3 49 ldr r3, [r7, #40] 50 add r2, r2, r3 51 ldr r3, [r7, #44] 52 ldr r3, [r3] 53 add r3, r3, r2 54 mov r0, r3 55 adds r7, r7, #20 56 mov sp, r7 57 @ sp needed 58 ldr r7, [sp], #4 59 bx lr 60 .size func, .-func 61 .section .rodata 62 .align 2 63 .LC0: 64 .ascii "%d\012\000" 65 .text 66 .align 1 67 .global main 68 .syntax unified 69 .thumb 70 .thumb_func 71 .fpu vfpv3-d16 72 .type main, %function 73 main: 74 @ args = 0, pretend = 0, frame = 24 75 @ frame_needed = 1, uses_anonymous_args = 0 76 push {r7, lr} 77 sub sp, sp, #48 78 add r7, sp, #24 79 str r0, [r7, #4] 80 str r1, [r7] 81 movs r3, #4 82 str r3, [r7, #20] 83 movs r3, #6 84 str r3, [r7, #16] 85 movs r3, #10 86 str r3, [r7, #12] 87 add r2, r7, #20 88 add r3, r7, #12 89 str r3, [sp, #20] 90 movs r3, #9 91 str r3, [sp, #16] 92 movs r3, #8 93 str r3, [sp, #12] 94 movs r3, #7 95 str r3, [sp, #8] 96 add r3, r7, #16 97 str r3, [sp, #4] 98 movs r3, #5 99 str r3, [sp] 100 mov r3, r2 101 movs r2, #3 102 movs r1, #2 103 movs r0, #1 104 bl func 105 mov r3, r0 106 mov r1, r3 107 movw r0, #:lower16:.LC0 108 movt r0, #:upper16:.LC0 109 bl printf 110 movs r3, #0 111 mov r0, r3 112 adds r7, r7, #24 113 mov sp, r7 114 @ sp needed 115 pop {r7, pc} 116 .size main, .-main 117 .ident "GCC: (Linaro GCC 7.3-2018.05) 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701]" 118 .section .note.GNU-stack,"",%progbits
在调用func函数时(bl func),参数存放情况如下:
ARM64:
1 .arch armv8-a 2 .file "a.c" 3 .text 4 .align 2 5 .global func 6 .type func, %function 7 func: 8 sub sp, sp, #48 9 str w0, [sp, 44] 10 str w1, [sp, 40] 11 str w2, [sp, 36] 12 str x3, [sp, 24] 13 str w4, [sp, 32] 14 str x5, [sp, 16] 15 str w6, [sp, 12] 16 str w7, [sp, 8] 17 ldr w1, [sp, 44] 18 ldr w0, [sp, 40] 19 add w1, w1, w0 20 ldr w0, [sp, 36] 21 add w1, w1, w0 22 ldr x0, [sp, 24] 23 ldr w0, [x0] 24 add w1, w1, w0 25 ldr w0, [sp, 32] 26 add w1, w1, w0 27 ldr x0, [sp, 16] 28 ldr w0, [x0] 29 add w1, w1, w0 30 ldr w0, [sp, 12] 31 add w1, w1, w0 32 ldr w0, [sp, 8] 33 add w1, w1, w0 34 ldr w0, [sp, 48] 35 add w1, w1, w0 36 ldr x0, [sp, 56] 37 ldr w0, [x0] 38 add w0, w1, w0 39 add sp, sp, 48 40 ret 41 .size func, .-func 42 .section .rodata 43 .align 3 44 .LC0: 45 .string "%d\n" 46 .text 47 .align 2 48 .global main 49 .type main, %function 50 main: 51 sub sp, sp, #64 52 stp x29, x30, [sp, 16] 53 add x29, sp, 16 54 str w0, [x29, 28] 55 str x1, [x29, 16] 56 mov w0, 4 57 str w0, [x29, 44] 58 mov w0, 6 59 str w0, [x29, 40] 60 mov w0, 10 61 str w0, [x29, 36] 62 add x2, x29, 40 63 add x1, x29, 44 64 add x0, x29, 36 65 str x0, [sp, 8] 66 mov w0, 9 67 str w0, [sp] 68 mov w7, 8 69 mov w6, 7 70 mov x5, x2 71 mov w4, 5 72 mov x3, x1 73 mov w2, 3 74 mov w1, 2 75 mov w0, 1 76 bl func 77 mov w1, w0 78 adrp x0, .LC0 79 add x0, x0, :lo12:.LC0 80 bl printf 81 mov w0, 0 82 ldp x29, x30, [sp, 16] 83 add sp, sp, 64 84 ret 85 .size main, .-main 86 .ident "GCC: (Linaro GCC 7.3-2018.05) 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701]" 87 .section .note.GNU-stack,"",@progbits
在调用func时(bl func)时,参数的存放情况如下: