AT&T 语法 hello world 有效,但英特尔语法不起作用



我正在使用GAS汇编程序为linux x86_64编写一个helloworld程序,下面是我在AT&T语法。

#.intel_syntax noprefix
.section .data
msg:
.ascii "hello worldn"
.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

这个作品和印刷"你好世界"。以下是intel语法:

.intel_syntax noprefix
.section .data
msg:
.ascii "hello worldn"
.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

这编译和运行良好,但不会打印"helloworld"。我假设错误在mov rsi, msg?如果是,正确的语法是什么?

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

如果你想用英特尔语法编程,我建议你选择一个更好的汇编程序,比如nasm。

您可以使用AT&T语法反汇编程序(如objdump -d(,以查看GAS.intel_syntax中的mov rsi, msg汇编为mov msg, %rsi,即来自32位绝对地址的64位加载。

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

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


BTW,您应该使用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

请注意,OSX将静态地址放在低32之外,因此即使在可执行文件中,您的地址也是64位的。无法将.data中的变量移动到Mac x86程序集的寄存器

最新更新