x86_64及aarch64架构传参规则
Posted rayylee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了x86_64及aarch64架构传参规则相关的知识,希望对你有一定的参考价值。
1. x86_64参数传递
x86_64汇编语言函数通过rdi、rsi、rdx、rcx、r8、r9(edi、esi、edx、ecx、r8、r9)传递。即:
- 1个参数: rdi(edi)
- 2个参数: rdi、rsi(edi、rsi)
- 3个参数: rdi、rsi、rdx(edi、esi、edx)
- 4个参数: rdi、rsi、rdx、rcx(edi、esi、edx、ecx)
- 5个参数: rdi、rsi、rdx、rcx、r8(edi、esi、edx、ecx、r8)
- 6个参数: rdi、rsi、rdx、rcx、r8、r9(edi、esi、edx、ecx、r8、r9)
当参数个数小于等于6个时, 使用寄存器rdi,rsi,rdx,rcx,r8,r9。从第7个参数开始通过栈传递, 顺序为从右往左入栈。
x64架构下一共有16个通用寄存器, 以’r’开头。而32位系统的寄存器是以’e’开头的. 实际上64位的系统架构也兼容了32位系统。我们仍然可以在64位系统中使用如’eax’等寄存器, 表示只使用’rax’寄存器的低32位, 其剩余的高32位会自动补全
/* x86_64.c */
# include<stdio.h>
void fun1(int a)
void fun2(int a,int b)
void fun3(int a,int b,int c)
void fun4(int a,int b,int c,int d)
void fun5(int a,int b,int c,int d,int e)
void fun6(int a,int b,int c,int d,int e,int f)
void fun7(int a,int b,int c,int d,int e,int f, int g)
void main()
int a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8;
fun1(a);
fun2(a,b);
fun3(a,b,c);
fun4(a,b,c,d);
fun5(a,b,c,d,e);
fun6(a,b,c,d,e,f);
fun7(a,b,c,d,e,f,g);
执行 gcc -S x86_64.c
movl -4(%rbp), %eax
movl %eax, %edi
call fun1
movl -8(%rbp), %edx
movl -4(%rbp), %eax
movl %edx, %esi
movl %eax, %edi
call fun2
movl -12(%rbp), %edx
movl -8(%rbp), %ecx
movl -4(%rbp), %eax
movl %ecx, %esi
movl %eax, %edi
call fun3
movl -16(%rbp), %ecx
movl -12(%rbp), %edx
movl -8(%rbp), %esi
movl -4(%rbp), %eax
movl %eax, %edi
call fun4
movl -20(%rbp), %edi
movl -16(%rbp), %ecx
movl -12(%rbp), %edx
movl -8(%rbp), %esi
movl -4(%rbp), %eax
movl %edi, %r8d
movl %eax, %edi
call fun5
movl -24(%rbp), %r8d
movl -20(%rbp), %edi
movl -16(%rbp), %ecx
movl -12(%rbp), %edx
movl -8(%rbp), %esi
movl -4(%rbp), %eax
movl %r8d, %r9d
movl %edi, %r8d
movl %eax, %edi
call fun6
movl -24(%rbp), %r9d
movl -20(%rbp), %r8d
movl -16(%rbp), %ecx
movl -12(%rbp), %edx
movl -8(%rbp), %esi
movl -4(%rbp), %eax
movl -28(%rbp), %edi
pushq %rdi
movl %eax, %edi
call fun7
2. aarch64参数传递
aarch64汇编语言函数前8个参数使用x0-x7寄存器(或低32位w0-w7寄存器)传递, 多于8个的参数均通过堆栈传递
/* aarch64.c */
# include<stdio.h>
void fun1(int a)
void fun2(int a,int b)
void fun3(int a,int b,int c)
void fun4(int a,int b,int c,int d)
void fun5(int a,int b,int c,int d,int e)
void fun6(int a,int b,int c,int d,int e,int f)
void fun7(int a,int b,int c,int d,int e,int f,int g)
void fun8(int a,int b,int c,int d,int e,int f,int g,int h)
void fun9(int a,int b,int c,int d,int e,int f,int g,int h,int i)
void main()
int a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9;
fun1(a);
fun2(a,b);
fun3(a,b,c);
fun4(a,b,c,d);
fun5(a,b,c,d,e);
fun6(a,b,c,d,e,f);
fun7(a,b,c,d,e,f,g);
fun8(a,b,c,d,e,f,g,h);
fun9(a,b,c,d,e,f,g,h,i);
执行 gcc -S aarch64.c
ldr w0, [sp, 76]
bl fun1
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun2
ldr w2, [sp, 68]
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun3
ldr w3, [sp, 64]
ldr w2, [sp, 68]
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun4
ldr w4, [sp, 60]
ldr w3, [sp, 64]
ldr w2, [sp, 68]
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun5
ldr w5, [sp, 56]
ldr w4, [sp, 60]
ldr w3, [sp, 64]
ldr w2, [sp, 68]
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun6
ldr w6, [sp, 52]
ldr w5, [sp, 56]
ldr w4, [sp, 60]
ldr w3, [sp, 64]
ldr w2, [sp, 68]
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun7
ldr w7, [sp, 48]
ldr w6, [sp, 52]
ldr w5, [sp, 56]
ldr w4, [sp, 60]
ldr w3, [sp, 64]
ldr w2, [sp, 68]
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun8
ldr w0, [sp, 44]
str w0, [sp]
ldr w7, [sp, 48]
ldr w6, [sp, 52]
ldr w5, [sp, 56]
ldr w4, [sp, 60]
ldr w3, [sp, 64]
ldr w2, [sp, 68]
ldr w1, [sp, 72]
ldr w0, [sp, 76]
bl fun9
以上是关于x86_64及aarch64架构传参规则的主要内容,如果未能解决你的问题,请参考以下文章
gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu 存在的问题
gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu 存在的问题
2017-11-19Linux基础知识:TP-Link WN823N无线网卡(RTL8192EU芯片)的X86-64及AARCH64驱动安装