Windows x64 上与 CS:APP x86-64 Linux 交换 long 示例函数的不同 asm

Different asm on Windows x64 from a CS:APP x86-64 Linux example function for swapping a long

我正在阅读CS:APP第3版(Ch3.pic 3.7 GAS汇编代码)

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

您的示例适用于 Linux、OS X 和其他非 Windows 平台(64 位 long, RDI、RSI 中的参数...)

您为 Windows x64 编译,它使用不同的调用约定(RCX、RDX 中的参数),long 是 32 位类型。


您在编译时也禁用了优化,因此 asm 充满了 store/reload 噪音。通过优化,它基本上是相同的,但寄存器不同。

顺便说一句,您可以使用 gcc -O3 -masm=intel 来获得更接近 NASM 语法的英特尔语法汇编。 (虽然它是 不是 NASM 语法;它的寻址模式类似于 MASM,并且仍然使用 GAS 指令。)