我正在阅读CS:APP第三版(Ch3 )。PIC3.7气体装配代码)
long exchange(long* xp, long y)
{
long x = *xp;
*xp = y;
return x;
}
exchange:
movq (%rdi), %rax
movq %rsi, (%rdi)
ret我想知道为什么下面的汇编代码(1.ASM:转换为nasm)不能工作?
我已经使用c2nasm将工作c函数分解成nasm汇编源代码。它与原来的装配完全不同。
main.cpp:
int main()
{
long a = 4;
// long b = exchange(&a, 3);
long b = exchange2(&a, 3);
printf("[a: %ld] [b: %ld]\n", a, b);
return 0;
}1.asm:
BITS 64
; default rel
default abs
global exchange2
section .text
exchange2:
;;; this code does not works
;;; program output -> [a: 4] [b: 0]
mov rax, [rdi]
mov [rdi], rsi
ret
;;; this code works, generated by c2nasm.
;;; program output -> [a: 3] [b: 4]
; push rbp
; mov rbp, rsp
; sub rsp, 16
; mov qword [rbp+10H], rcx
; mov dword [rbp+18H], edx
; mov rax, qword [rbp+10H]
; mov eax, dword [rax]
; mov dword [rbp-4H], eax
; mov rax, qword [rbp+10H]
; mov edx, dword [rbp+18H]
; mov dword [rax], edx
; mov eax, dword [rbp-4H]
; leave
; ret编辑:谢谢!
Windows x64 long long exchange(long long*, long long)的工作版本
BITS 64
default rel
global _exchange2 ; Windows name-mangling prepends _ to C names
section .text
_exchange2:
mov rax, [rcx]
mov [rcx], rdx
ret发布于 2019-03-21 06:32:14
您的示例是x86-64系统V,用于Linux、OS和其他非Windows平台( RDI中的64位long、args、RSI、.)
您是为Windows编译的,它使用了不同的调用约定( RCX中的args,RDX中的args),而long是32位类型。
此外,您在编译时禁用了优化,因此asm充满了存储/重新加载噪声。通过优化,它基本上是相同的,但是有不同的寄存器。
顺便说一句,您可以使用gcc -O3 -masm=intel来获得英特尔语法程序集,它更接近于NASM语法。(这不是NASM语法;它类似于MASM,用于寻址模式,并且仍然使用GAS指令。)
https://stackoverflow.com/questions/55274794
复制相似问题