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

查看:79
本文介绍了在不是地址/指针的值上使用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没有必须对内存地址进行操作,并且计算一个地址,它实际上并不会从结果中 read ,因此,直到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).

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

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