我正在使用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
中?如果是这样,正确的语法是什么?
答案 0 :(得分:4)
尝试mov rsi, offset msg
。 gas使用类似masm的语法,其中mov rsi, msg
将msg
的内容移到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