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驱动安装

解决警告:没有规则来处理架构 x86_64 的文件

华为发布AArch64/Arm64 硬件的 Linux 镜像内存支持