Ale*_*ing 2 assembly gnu-assembler intel-syntax
我有一条用Intel语法编写的指令(使用gas作为汇编程序),看起来像这样:
mov rdx, msg_size
...
msg: .ascii "Hello, world!\n"
.set msg_size, . - msg
Run Code Online (Sandbox Code Playgroud)
但是该mov指令正在汇编到mov 0xe,%rdx,而不是mov $0xe,%rdx我期望的那样。我应该如何编写第一条指令(或的定义msg_size)以获得预期的行为?
在GAS .intel_syntax noprefix模式下:
OFFSET symbol像AT&T一样工作$symbol。这有点像MASM。symbol类似于AT&T symbol(即取消引用)。[symbol]在GAS和NASM / YASM中始终是有效的地址,而不是立即的地址。 LEA不会从地址加载,但仍使用内存操作数机器编码。(这就是为什么它使用相同的语法)。提示:如果您了解AT&T语法或NASM语法,请使用该语法生成所需的编码,然后反汇编objdump -Mintel以找到适用于的正确语法.intel_syntax noprefx。
顺便说一句,据我了解,没有开源项目包含GAS intel_syntax源代码。如果使用天然气,则使用AT&T语法。否则,他们使用NASM / YASM。(有时您还会在开放源代码项目中看到MSVC内联汇编)。
GNU as .intel_syntax noprefixmode有点像MASM,除了没有魔术取决于符号的定义方式。
mov rdx, symbol永远是负担。符号的值是其地址。也就是说,使用.set创建(或修改)符号的行为与将标签贴在某物上的行为完全相同。
(除非symbol使用symbol=123或定义为汇编时间常数,否则.equ symbol, 123它是立即移动的。)
mov rdx, OFFSET symbol将组装到mov r/m64, imm32。我忘记了intel-syntax模式是否可以使用大操作数进行mov组装movabs r64, imm64,但这无关紧要,因为静态数据/代码地址始终位于虚拟地址空间的低2GiB中,因此它们适合32位符号扩展的立即数。
(这样可以安全地编写代码mov edx, OFFSET symbol,实际上,您应该始终这样做或使用lea rdx, [rip + symbol],切勿对符号进行32位立即数扩展,除非要编写的代码将加载到2GB的虚拟地址空间中。)
| 归档时间: |
|
| 查看次数: |
518 次 |
| 最近记录: |