LEA 是否在负标度下有效,或者 SUB 是否在标度寄存器上有效?
我有两个寄存器像这样映射到变量
%rdi = x, %rsi = y
我想让 y = y - 4x
我的试验是这样的。我减去 x 四次得到 y - 4x。
subq %rdi, %rsi # y = y - x
subq %rdi, %rsi # y = y - 2x
subq %rdi, %rsi # y = y - 3x
subq %rdi, %rsi # y = y - 4x
但我想只用一行代码来完成。
我考虑过在这种情况下使用 leaq。leaq (%rsi, %rdi, 4), %rsi # y = y + 4x
但如您所见,现在我添加 4x,而不是减去 4x。
所以我的问题是,
- leaq (%rsi, %rdi, -4), %rsi
这是一个有效的操作吗?我知道比例因子必须是 2 的幂,如 1、2、4...,但它可以是负数,如 -4 吗? - subq -4 * %rdi, %rsi
这也有效吗?我想知道是否可以直接对寄存器值执行乘法。
I have two registers mapped like this to a variable
%rdi = x, %rsi = y
I want to make y = y - 4x
My trial goes like this. I subtracted x four times to get y - 4x.
subq %rdi, %rsi # y = y - x
subq %rdi, %rsi # y = y - 2x
subq %rdi, %rsi # y = y - 3x
subq %rdi, %rsi # y = y - 4x
But I want to finish with just one line of code.
I thought about using leaq in this situation.leaq (%rsi, %rdi, 4), %rsi # y = y + 4x
But as you see, now I'm adding 4x instead of subtracting 4x.
So my question is,
- leaq (%rsi, %rdi, -4), %rsi
would this be a vaild operation? I know the scaling factor has to be a power of 2 like 1,2,4... but can it be a negative number like -4? - subq -4 * %rdi, %rsi
would this also be valid? I want to know if I could perform a multiplication to a register value directly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不会。在机器代码中,标度被编码为 2 位(在“SIB”字节中,其中还有 3 位用于确定索引寄存器,3 位用于确定基址寄存器 - 没有未使用的位)。 2 个缩放位被解释为移位计数(例如
<< 0
、<< 1
、<< 2
,<< 3
) 本质上与乘数相同(例如* 1
,* 2
,* 4< /代码>, <代码>* 8)。
秤不能直接在收银机上使用。添加这种复杂性是为了使访问数组变得快速/简单;并且只能用于确定地址(用于使用
lea
指令加载地址,或用于访问内存)。还有其他指令对寄存器值进行乘法(对于通用/整数寄存器,移位、mul、imul 和 aad,以及更多关于浮点和 SIMD 寄存器的信息)。如果您想要执行“融合乘法和加法”,那么您的选择是
aad
(乘数必须为常量的 8 位)、lea
和 SIMD扩展。理论上;可能会为 80x86 机器代码发明一种新的汇编语言(就像 AT&T 为 80x86 发明一种与英特尔汇编语言不匹配的汇编语言一样);汇编器可以做任何它喜欢做的事情(只要它可以将其“指令”的想法转换为机器语言)。
例如,新的汇编语言可以接受 movq %rsi+%rdi*4, %rsi(并将其转换为 leaq (%rsi, %rdi, 4), % 的机器代码) rsi)。同样,新的汇编器可以接受 subq -4 * %rdi, %rsi(并将其转换为 leaq (%rsi, %rdi, 4), % 的机器代码) rsi),只要后面的指令不依赖于这些标志即可。
No. In machine code the scale is encoded as 2 bits (in a "SIB" byte, which also has 3 bits to determine the index register and 3 bit to determine the base register - there's no unused bits). The 2 scale bits are interpreted as a shift count (like
<< 0
,<< 1
,<< 2
,<< 3
) which is essentially the same as a multiplier (like* 1
,* 2
,* 4
,* 8
).The scale can't be used directly on a register. This kind of complexity was added to make accessing arrays fast/easy; and can only be used to determine an address (either for loading an address with the
lea
instruction, or for accessing memory).There are other instructions that do a multiplication to a register value though (shifts,
mul
,imul
, andaad
for general/integer registers, plus more for floating point and SIMD registers). If you want to do a "fused multiply and add" then your choices areaad
(which is 8 bits where the multiplier has to be a constant),lea
, and SIMD extensions.In theory; it would be possible to invent a new assembly language for 80x86 machine code (in the same way that AT&T invented an assembly language for 80x86 that doesn't match Intel's assembly language); where the assembler can do whatever it likes (as long as it can convert its idea of "instructions" into machine language).
For example, a new assembly language could accept
movq %rsi+%rdi*4, %rsi
(and convert it to the machine code forleaq (%rsi, %rdi, 4), %rsi
). In the same way, a new assembler could acceptsubq -4 * %rdi, %rsi
(and convert it to the machine code forleaq (%rsi, %rdi, 4), %rsi
) as long as no later instruction depends on the flags.