为什么VS模拟rax,rax,0而不是简单的移动
Why VS does imul rax,rax,0 instead of simple move?
我正在查看Visual Studio为这个简单的x64程序生成的程序集:
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
为什么它要做模拟rax,rax,0而不是简单的mov rax,0,甚至xor rax,rax?如果有的话,imul是如何更高效的?
Kamac
原因是程序集正在计算数组中恰好在堆栈上的Point
对象的偏移量,以及到变量b
的偏移量。
带三(3)个操作数状态的imul
英特尔文档:
三操作数形式--此形式需要一个目标操作数(第一个操作数)和两个源操作数(第二个和第三个操作数)。这里,第一个源操作数(可以是通用寄存器或存储器位置)乘以第二个源操作数(立即数)。中间产品(第一个源操作数大小的两倍)被截断并存储在目标操作数(通用寄存器)中。
在您的情况下,它计算数组中对象的偏移量,从而寻址堆栈上的第一个(第零个)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
指令。所有这些都解析为CCD_ 7。
我认为你没有进行积极的优化编译。当进行直接编译(没有优化、调试等)时,编译器不会对寻址做出任何假设。
与clang的比较
在带有clang 3.9.0
且没有优化标志的OS X(El Capitan)上,一旦Point
对象在数组中实例化,.b = 2
的赋值就简单地为:
mov dword ptr [rbp - 44], 2
在这种情况下,clang
在偏移方面非常聪明,并在默认优化期间解决了寻址问题。
相关文章:
- 在c++中用vector填充一个简单的动态数组
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 一种在C++中读取TXT配置文件的简单方法
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 显示错误输出的简单数组排序程序
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 退出简单while循环时出现问题
- 为什么简单的算术减法在"if"条件下不起作用?
- C++-字符串是否包含一个带有简单循环的单词
- 关于 c++ 函数中指针赋值的简单问题
- 从函数返回任意简单类型的数据
- 如何在没有函数的情况下编写此代码并使C++更简单?
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 当简单捕获中的标识符显示为参数的声明符 ID 时,没有编译器诊断
- 如何使用 samtools C API 构建一个简单的主.cpp文件
- 为什么VS模拟rax,rax,0而不是简单的移动