AT&T语法hello world有效,但intel语法无效

时间:2018-07-26 16:45:32

标签: assembly x86-64 gas intel-syntax

我正在使用GAS汇编器为Linux x86_64编写一个hello world程序,这是我用AT&T语法编写的代码。

#.intel_syntax noprefix

.section .data
    msg:
        .ascii "hello world\n"
.section .text
.globl _start
_start:
    movq  $1, %rax
    movq  $1, %rdi
    movq  $msg, %rsi
    movq  $12, %rdx
    syscall

    movq  $60, %rax
    movq  $0, %rdi
    syscall

这有效并打印“ hello world”。这是intel语法:

.intel_syntax noprefix

.section .data
    msg:
        .ascii "hello world\n"
.section .text
.globl _start
_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, 12
    syscall

    mov rax, 60
    mov rdi, 0
    syscall

这可以编译并正常运行,但不会打印“ hello world”。我假设错误是在mov rsi, msg中?如果是这样,正确的语法是什么?

2 个答案:

答案 0 :(得分:4)

尝试mov rsi, offset msg。 gas使用类似masm的语法,其中mov rsi, msgmsg的内容移到rsi而不是地址。必须使用offset关键字来避免此问题。

如果要使用Intel语法编程,建议您选择像nasm这样更好的汇编程序。

答案 1 :(得分:3)

您可以使用AT&T语法反汇编程序(例如objdump -d)来查看GAS mov rsi, msg中的.intel_syntax可以组装成mov msg, %rsi,这是从32位位绝对地址。

或使用objdump -d -Mintel查看适用于您的工作版本的英特尔语法反汇编。

GDB具有set disassembly-flavor intel或att,因此您甚至可以在一个调试会话中翻转。


然后顺便说一句,您应该使用相对RIP的LEA将64位静态地址放入寄存器。比mov r64, imm64

更有效
lea   msg(%rip), %rsi    # AT&T

lea   rsi, [msg + rip]  # GAS .intel_syntax

lea   rsi, [rel msg]     ; NASM

(但在静态标签位于虚拟地址空间的低31位中,但其位置依赖性可执行文件的效率比mov r32, imm32低)

 ## In x86-64 position-dependent executables on Linux

 mov  $msg, %esi            # AT&T

 mov   esi, OFFSET msg      # GAS .intel_syntax

 mov   esi, msg          ; NASM

请注意,OS X将静态地址放在低32位之外,因此,即使在可执行文件中,您的地址也是64位。 Unable to move variables in .data to registers with Mac x86 Assembly