AT&T 语法 hello world 有效,但 intel 语法无效
AT&T syntax hello world works but intel syntax does not
我正在使用 GAS 汇编器为 linux x86_64 编写一个 hello world 程序,这里是我的 AT&T 语法代码。
#.intel_syntax noprefix
.section .data
msg:
.ascii "hello world\n"
.section .text
.globl _start
_start:
movq , %rax
movq , %rdi
movq $msg, %rsi
movq , %rdx
syscall
movq , %rax
movq [=10=], %rdi
syscall
这有效并打印 "hello world"。这是英特尔语法:
.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
?如果是这样,正确的语法是什么?
尝试mov rsi, offset msg
。 gas 使用类似 masm 的语法,其中 mov rsi, msg
将 msg
的内容移动到 rsi
而不是移动地址。必须使用 offset
关键字来避免此问题。
如果你想用 Intel 语法编程,我建议你选择一个更好的汇编器,比如 nasm。
您可以使用 AT&T 语法反汇编程序(如 objdump -d
)来查看 GAS .intel_syntax
中的 mov rsi, msg
汇编为 mov msg, %rsi
,从32 位绝对地址。
或使用 objdump -d -Mintel
查看适用于您的工作版本的 Intel 语法反汇编。
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
(但在位置相关的可执行文件中效率低于 mov r32, imm32
,其中静态标签位于虚拟地址的低 31 位 space。)
## 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 位的。
我正在使用 GAS 汇编器为 linux x86_64 编写一个 hello world 程序,这里是我的 AT&T 语法代码。
#.intel_syntax noprefix
.section .data
msg:
.ascii "hello world\n"
.section .text
.globl _start
_start:
movq , %rax
movq , %rdi
movq $msg, %rsi
movq , %rdx
syscall
movq , %rax
movq [=10=], %rdi
syscall
这有效并打印 "hello world"。这是英特尔语法:
.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
?如果是这样,正确的语法是什么?
尝试mov rsi, offset msg
。 gas 使用类似 masm 的语法,其中 mov rsi, msg
将 msg
的内容移动到 rsi
而不是移动地址。必须使用 offset
关键字来避免此问题。
如果你想用 Intel 语法编程,我建议你选择一个更好的汇编器,比如 nasm。
您可以使用 AT&T 语法反汇编程序(如 objdump -d
)来查看 GAS .intel_syntax
中的 mov rsi, msg
汇编为 mov msg, %rsi
,从32 位绝对地址。
或使用 objdump -d -Mintel
查看适用于您的工作版本的 Intel 语法反汇编。
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
(但在位置相关的可执行文件中效率低于 mov r32, imm32
,其中静态标签位于虚拟地址的低 31 位 space。)
## 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 位的。