交换寄存器内容的汇编程序
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
我正在尝试编写一个真正简单的汇编程序来交换寄存器的内容。这是我试过的:
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