gpt4 book ai didi

c++ - 为什么 VS 做 imul rax,rax,0 而不是简单的移动?

转载 作者:行者123 更新时间:2023-11-28 00:02:49 25 4
gpt4 key购买 nike

我正在查看为这个简单的 x64 程序生成的程序集 Visual Studio:

struct Point {
int a, b;

Point() {
a = 0; b = 1;
}
};

int main(int argc, char* argv[])
{
Point arr[3];
arr[0].b = 2;
return 0;
}

当它遇到 arr[0].b = 2 时,它会生成:

mov eax, 8
imul rax, rax, 0
mov dword ptr [rbp+rax+4],2

为什么它执行 imul rax, rax, 0 而不是简单的 mov rax, 0,甚至 xor rax, rax? imul 如何更有效?

最佳答案

卡马克

原因是因为程序集正在计算数组中 Point 对象的偏移量,它恰好在堆栈上,以及变量 b< 的偏移量.

具有三 (3) 个操作数状态的 imul 的英特尔文档:

Three-operand form — This form requires a destination operand (the first operand) and two source operands (the second and the third operands). Here, the first source operand (which can be a general-purpose register or a memory location) is multiplied by the second source operand (an immediate value). The intermediate product (twice the size of the first source operand) is truncated and stored in the destination operand (a general-purpose register).

在您的情况下,它正在计算数组中对象的偏移量,这导致寻址堆栈上的第一个(第零个)Point 位置。解决该问题后,将添加 .b 的偏移量,即 +4。如此分解:

mov  eax,8                   ; prepare to offset into the Point array
imul rax, rax, 0 ; Calculate which Point object is being referred to
mov dword ptr [rbp+rax+4],2 ; Add the offset to b and move value 2 in

说明。所有这些都解析为 arr[0].b = 2

我认为您没有使用积极的优化进行编译。当进行直接编译(无优化、调试等)时,编译器不会对寻址做出任何假设。

与clang的对比

在带有 clang 3.9.0 且没有优化标志的 OS X (El Capitan) 上,一旦 Point 对象在数组中实例化, 的赋值.b = 2 就是:

mov dword ptr [rbp - 44], 2

在这种情况下,clang 在默认优化期间对偏移和解析寻址非常聪明。

关于c++ - 为什么 VS 做 imul rax,rax,0 而不是简单的移动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37629283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com