10

x86/x64 に慣れるために、 http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.htmlのいくつかのチュートリアルに取り組んでいます。このチュートリアル コードは、AT&T 構文を使用する提供されたコードを使用して問題なくコンパイルおよび実行されます。

.global main
.text
main:                               # This is called by C library's 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's 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 に詳しくないので、何かが足りないのかもしれません。何か案は?

4

1 に答える 1

14

AT&T の構文でmov $message, %rdiは、$即時を意味し、メッセージのアドレスを意味します。

GAS の Intel 構文では、mov rdi, message絶対アドレス指定を意味し、メッセージの内容を意味します。messageの実​​際のアドレスを取得するには、キーワード:を指定する必要があります。offsetmov rdi, offset message

2 つのバイナリを分解すると、違いが分かります。

AT&T:

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

インテル:

0000000000000000 <main>:
0:   48 8b 3c 25 00 00 00 00    mov    0x0,%rdi
     
于 2013-04-20T14:23:26.993 に答える