Отличается asm на Windows x64 от примера функции Linux CS: APP x86-64 для замены длинного - PullRequest
0 голосов
/ 21 марта 2019

Я читаю CS: APP 3-е издание (Ch3. Рис. 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) не работает?

я разбирал рабочую функцию c для получения исходного кода сборки nasm с помощью c2nasm.это совершенно отличается от оригинальной сборки.

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

1 Ответ

2 голосов
/ 21 марта 2019

Ваш пример для x86-64 System V ABI, используемого на Linux, OS X и других платформах, отличных от Windows (64-битная long, аргументы в RDI, RSI, ...)

Вы скомпилировали для Windows x64, которая использует другое соглашение о вызовах (аргументы в RCX, RDX), а long - это 32-разрядный тип.


Также вы скомпилировали с отключенной оптимизацией, поэтомуAsm полон шума хранения / перезагрузки.С оптимизацией это будет в основном то же самое, но с другими регистрами.

Кстати, вы можете использовать gcc -O3 -masm=intel, чтобы получить синтаксическую сборку Intel, которая намного ближе к синтаксису NASM.(Это не синтаксис NASM, хотя; он похож на MASM для режимов адресации и все еще использует директивы GAS.)

...