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

问题描述 投票:0回答:1

我正在阅读CS:APP第3版(第3章。图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步:

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
assembly x86-64 nasm calling-convention win64
1个回答
2
投票

您的示例适用于x86-64 System V ABI,用于Linux,OS X和其他非Windows平台(64位long,RDI,RSI中的args,...)

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


你也编译了禁用优化,因此asm充满了存储/重载噪声。通过优化,它基本上是相同的,但具有不同的寄存器。

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

© www.soinside.com 2019 - 2024. All rights reserved.