Почему переход с AT & T на синтаксис Intel делает этот учебник segfault с использованием GAS?

Я изучаю некоторые учебники по http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html, чтобы ознакомиться с x86/x64. Этот код учебника компилируется и запускается без икоты с использованием предоставленного кода, который использует синтаксис AT & T:

.global main
.text
main:                               # This is called by C library startup code
    mov     $message, %rdi          # First integer (or pointer) parameter in %edi
    call    puts                    # puts("Hello, World")
    ret                             # Return to C library code
message:
    .asciz "Hello, World"           # asciz puts a 0x00 byte at the end

Однако, когда я конвертирую этот код в синтаксис Intel, я получаю ошибку "Ошибка сегментации".

.intel_syntax noprefix
.global main
.text
main:                               # This is called by C library startup code
    mov     rdi, message            # First integer (or pointer) parameter in %edi
    call    puts                    # puts("Hello, World")
    ret                             # Return to C library code
message:
    .asciz "Hello, World"           # asciz puts a 0x00 byte at the end

Я не знаком с x86, поэтому, возможно, я что-то упустил. Любые идеи?

Ответ 1

В синтаксисе AT & T, mov $message, %rdi, $ означает немедленный, то есть адрес сообщения.

В синтаксисе GAS Intel mov rdi, message означает абсолютную адресацию, что означает сообщение content. Чтобы получить фактический адрес сообщения, вам нужно указать ключевое слово offset: mov rdi, offset message.

Дразнитесь к двум двоичным файлам, которые показывают разницу:

AT & Т:

0000000000000000 <main>:
0:   48 c7 c7 00 00 00 00    mov    $0x0,%rdi

Intel:

0000000000000000 <main>:
0:   48 8b 3c 25 00 00 00    mov    0x0,%rdi