10

我正在阅读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'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处的内容。要获取message的实际地址,您需要提供关键字:。offsetmov rdi, offset message

两个二进制文件的 Disassebly 显示了差异:

美国电话电报公司:

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 回答