x86-64 汇编中的交换函数

Swap function in x86-64 assembly

我正在尝试编写以下形式的函数:

void swap(int *a, int *b);

在 x86-64 汇编中。

[section .text]
global  swap ;
swap: mov ecx, [esp+8] ; copy parameter a to ecx
mov edx, [esp+16] ; copy parameter b to edx
mov eax, [ecx] ; copy a into eax
xchg eax, [edx] ; exchange eax with b
mov [ecx], eax;
ret;

我使用以下命令在 Linux 上编译它:

nasm -f elf64 swap.asm

编译无误。主文件如下:

 #include <stdio.h>
 extern void swap(int *a,int *b);
 int main(){
          int a = 10, int b = 20;
          swap(&a,&b);
          printf("a = %d b = %d\n",a,b );
          return 0;
 }

主文件也编译通过。但是,当我 运行 这个程序时,我得到了一个分段错误。有什么我犯错的想法吗?

简短回答:您期待错误的调用约定。您还使用了 32 位指针而不是 64 位指针。


Linux x86-64 应用程序使用 System V AMD64 ABI,它在寄存器 RDIRSI、[=13= 中传递了前 6 个“常规”参数], RCX, R8, R9。输入时,aRDI 中,bRSI.

对于您的 swap,这会简化您的代码,因为您不需要从堆栈指针的偏移量加载。


swap:
    mov eax, [rdi]    ; *a to EAX
    xchg eax, [rsi]   ; Exchange *a with *b
    mov [rdi], eax    ; EAX to *a
    ret

请注意,这不一定是最有效的低级别交换方法。尽管它的指令更少,但这不一定更好,而且更糟 performance-wise。 GCC 10 for x86-64 向寄存器生成负载,然后将两者翻转存储。