交换寄存器内容的汇编程序

Assembler program to swap contents of registers

我正在尝试编写一个真正简单的汇编程序来交换寄存器的内容。这是我试过的:

movq (%rcx), %rax
movq (%rbx), %rdx
movq %rdx, (%rcx)
movq %rax, (%rbx)
ret

它给我分段错误。

这是一个在 c:

中的工作程序的例子
void swap(int64_t *a, int64_t *b) {
    int64_t c = *a;
    *a = *b;
    *b = c;
}

参见:https://en.wikipedia.org/wiki/X86_calling_conventions

您忘记提及您是针对 Microsoft/Win x64 还是针对 System V AMD64 ABI [或完全针对其他东西] 进行编译。

您正在使用 AT&T asm 语法,所以我假设您需要 SysV 调用约定。 (因为像 GCC 和 GAS 这样的工具在 Linux / MacOS 上更常见。但是如果你在 Windows 上使用 MinGW w64 那么你会想要 Windows 约定。)


您假设参数位于:%rcx%rbx。这 not 符合 either 约定 [尽管它有点接近 MS ABI]

对于 System V AMD64 ABI(例如 Linux、BSD、MacOS),前两个参数分别传入 %rdi%rsi。并且,not%rdx%rcx 中(用于第 3 个和第 4 个参数)。

您始终可以使用 %rax%rdx 作为临时寄存器,因为 %rax 保存函数 return 值,而 %rdx 是一个 arg reg 所以调用者不会期望它们被保留。

那么,你想要:

# Non-Windows
movq (%rdi),%rax
movq (%rsi),%rdx
movq %rdx,(%rdi)
movq %rax,(%rsi)
ret

对于 MS 64 位,arg 寄存器是:%rcx, %rdx, %r8, %r9

所以,你想要:

# Windows
movq (%rcx),%rax
movq (%rdx),%r8
movq %r8,(%rcx)
movq %rax,(%rdx)
ret