[英]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,它具有在寄存器RDI
、 RSI
、 RDX
、 RCX
、 R8
、 R9
傳遞的前 6 個“常規”參數。 進入時, a
在RDI
, b
在RSI
。
在您的swap
的情況下,這簡化了您的代碼,因為您不需要從堆棧指針的偏移量加載。
swap:
mov eax, [rdi] ; *a to EAX
xchg eax, [rsi] ; Exchange *a with *b
mov [rdi], eax ; EAX to *a
ret
請注意,這不一定是交換的最有效方法,在低級別。 盡管指令較少,但這並不一定更好,而且在性能方面更差。 適用於 x86-64 的 GCC 10生成加載到寄存器,然后存儲兩個翻轉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.