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

标签 assembly x86 intel gnu-assembler att

我正在研究http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html上的一些教程,以熟悉x86/x64。本教程代码使用提供的使用AT&T语法的代码进行编译和运行,不会出现打h的情况:

.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语法时,出现“Segmentation fault”错误。
.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不熟悉,所以也许我缺少了一些东西。有任何想法吗?

最佳答案

在AT&T语法中,mov $message, %rdi$表示立即数,表示消息的地址。
在GAS的Intel语法中,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 00    mov    0x0,%rdi
     

关于assembly - 为什么从AT&T切换到Intel语法会使本教程使用GAS出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16121173/

相关文章:

c - 如何使用 GCC 更改基址?

c - 使用 AVX 内在函数对 __m512i 中的 8 位整数求和

C 代码在 Intel Xeon E5-2650 上的性能

SHL eax、ecx 的程序集 x86 错误

assembly - NASM:声明字符串时为 "comma, colon, decorator or end of line expected after operand"

macos - Mac OS X : YASM: error: macho: sorry, 无法在 64 模式下应用 32 位绝对重定位

x86 - 读取当前非核心频率并设置非核心倍频器

windows - 从 Windows 角度看 x86 程序集?

c - 系统如何确保内存和缓存之间的一致性

c++ - 在 Intel C++ 上检测 C++0x 模式?