为什么从AT& T切换到Intel语法会使本教程使用GAS进行段错误?

时间:2013-04-20 14:01:01

标签: assembly x86 intel gas att

我正在研究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,所以也许我错过了一些东西。有什么想法吗?

1 个答案:

答案 0 :(得分:12)

在AT& T语法mov $message, %rdi中,$表示立即,表示消息的地址

在GAS的英特尔语法中,mov rdi, message表示绝对寻址,即消息中的内容。要获取消息的实际地址,您需要提供offset关键字:mov rdi, offset message

两个二进制文件的拆解显示了不同之处:

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    mov    0x0,%rdi