assembly - x86 指令“movb $5, var(,1)”
问题描述
我正在阅读关于 AT&T 语法的 x86 汇编教程,我遇到了这个说明
movb $5, var(,1)
— 将值 5 存储到位置 var 的字节中。
(,1)
aftervar
表示什么?这种后缀的一般语法是什么?
解决方案
至少可以说这是非常规的风格。我以前从未见过有人写过这样的东西,用于解决没有寄存器的静态标签。
这可能是试图指示一个 SIB 字节(没有基址或索引),而不是允许汇编器使用只有 ModRM 字节的较短编码。
(是的,这是可能的。32 位寻址模式有 2 种冗余方式来编码[disp32]
绝对地址。x86-64 将较短的一种重新定义为 RIP 相对寻址。另请参阅rbp not allowed as SIB base?)
但是当前的 GAS 会忽略它并将其编码为与 just 相同var
。
因此,也许它试图提醒您这是一个内存操作数,就像总是[var]
在 Intel 语法中使用而不是mov var, al
(这在 MASM 风格的 Intel 语法风格中有效,例如 GNU .intel_syntax
,但不是 NASM)。
这种后缀的一般语法是什么?
或者,也许他们只是为了始终使用disp(basereg, idxreg, scale)
内存操作数的语法保持一致性,省略未使用的部分。
测试来源:
var: # this won't be in writeable memory, it will assemble but not run
movb $5, var
movb $5, var(,1)
movb $5, (var) # turns out this is valid, too!
#movb $5, var(%rip) # RIP-relative is x86-64 only, but it's recommended when available.
# movb $5, var() # Error: junk `()' after expression
# movb $5, (var,,1) # also invalid
# movb $5, (var,%ecx,1) # also invalid.
# movb $5, (var+%eax,%ecx,1) # also invalid.
as --version
GNU assembler (GNU Binutils) 2.31.1
在我的系统上打印。
$ gcc -m32 -no-pie -nostdlib foo.s
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008049000
# I just wanted a linked binary with real addresses filled in, not to run it.
# entry = start of the .text section is fine.
$ objdump -drwC -Mintel a.out
08049000 <var>:
8049000: c6 05 00 90 04 08 05 mov BYTE PTR ds:0x8049000,0x5
8049007: c6 05 00 90 04 08 05 mov BYTE PTR ds:0x8049000,0x5
804900e: c6 05 00 90 04 08 05 mov BYTE PTR ds:0x8049000,0x5
Clang 7.0 的内置汇编器也接受 GAS 所做的所有 3 个变体,生成相同的二进制文件。(至少.text
我正在拆卸的部分;可能在另一部分的某个地方有所不同。)
那么也许cmp $1, (var)
是使内存操作数显式的好方法? 但这并不是很好,因为与 Intel 语法不同,您不能只向其中添加寄存器,您必须移出var
括号。
推荐阅读
- python - 仅从熊猫列中提取日期
- c# - 更改 Windows 客户端的 I/O 缓冲区
- android - 使用生物识别 androidX 库 1.1.0 崩溃
- python - Python:将多列与一列进行比较,并将大于该列的值替换为 NaN
- cucumber - 特征文件包含(和/。如何转义?
- css - Froala tableCellStyles 边框未更新
- victory-charts - 在胜利图上根据 y 轴绘制彩色背景
- unity3d - 我有一个 Unity 图像格式问题
- php - 如何从 VS Code 侧边栏中隐藏二进制文件?
- php - PHP 中带有自动欢迎电子邮件的注册表单