对不是地址/指针的值使用 LEA? [英] Using LEA on values that aren't addresses / pointers?

查看:11
本文介绍了对不是地址/指针的值使用 LEA?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解地址计算指令的工作原理,尤其是使用 leaq 命令.然后,当我看到使用 leaq 进行算术计算的示例时,我感到困惑.比如下面的C代码,

I was trying to understand how Address Computation Instruction works, especially with leaq command. Then I get confused when I see examples using leaq to do arithmetic computation. For example, the following C code,

long m12(long x) {
return x*12;
}

在组装中,

leaq (%rdi, %rdi, 2), %rax
salq $2, $rax

如果我的理解是对的,leaq 应该移动任何地址 (%rdi, %rdi, 2),应该是 2*%rdi+%rdi,求值为进入%rax.我感到困惑的是,因为值 x 存储在 %rdi 中,这只是内存地址,为什么 %rdi 乘以 3 然后将这个 内存地址 左移 2 是等于 x 乘以 12?这不是当我们将 %rdi 乘以 3 时,我们会跳转到另一个不保存值 x 的内存地址吗?

If my understanding is right, leaq should move whatever address (%rdi, %rdi, 2), which should be 2*%rdi+%rdi, evaluate to into %rax. What I get confused is since value x is stored in %rdi, which is just memory address, why does times %rdi by 3 then left shift this memory address by 2 is equal to x times 12? Isn't that when we times %rdi by 3, we jump to another memory address which does not hold value x?

推荐答案

leaq 不需要操作内存地址,它计算em> 一个地址,它实际上并不读取结果,所以直到 mov 或类似的尝试使用它,这只是添加一个数字的一​​种深奥的方式, 加上 1、2、4 或 8 次另一个数字(或在这种情况下相同的数字).正如您所见,出于数学目的,它经常被滥用".2*%rdi+%rdi 只是 3 * %rdi,所以它计算 x * 3 而不涉及 CPU 上的乘法器单元.

leaq doesn't have to operate on memory addresses, and it computes an address, it doesn't actually read from the result, so until a mov or the like tries to use it, it's just an esoteric way to add one number, plus 1, 2, 4 or 8 times another number (or the same number in this case). It's frequently "abused" for mathematical purposes, as you see. 2*%rdi+%rdi is just 3 * %rdi, so it's computing x * 3 without involving the multiplier unit on the CPU.

类似地,左移,对于整数,由于二进制数的工作方式(十进制数的工作方式相同,在右侧添加零乘以 10).

Similarly, left shifting, for integers, doubles the value for every bit shifted (every zero added to the right), thanks to the way binary numbers work (the same way in decimal numbers, adding zeroes on the right multiplies by 10).

所以这是滥用 leaq 指令来完成乘以 3,然后将结果移位以实现进一步乘以 4,最终结果乘以 12,而实际上从未使用乘法指令(它大概认为会运行得更慢,据我所知它可能是对的;猜测编译器通常是一场失败的游戏).

So this is abusing the leaq instruction to accomplish multiplication by 3, then shifting the result to achieve a further multiplication by 4, for a final result of multiplying by 12 without ever actually using a multiply instruction (which it presumably believes would run more slowly, and for all I know it could be right; second-guessing the compiler is usually a losing game).

:明确地说,这不是误用意义上的滥用,只是以一种与您隐含的目的不明确一致的方式使用它"d 期望从它的名字.以这种方式使用它是 100% 可以的.

: To be clear, it's not abuse in the sense of misuse, just using it in a way that doesn't clearly align with the implied purpose you'd expect from its name. It's 100% okay to use it this way.

这篇关于对不是地址/指针的值使用 LEA?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆