这可能是一个菜鸟问题,因为我刚刚开始深入研究c ++代码的反汇编,以检查编译器最终为我做了些什么。基本上我有一些c ++代码(这是一个玩具示例):
const int SIZE = 10000000;
for(auto i = 0; i < SIZE; i++)
{
giantVector[i] = giantVector[i] * giantVector[i];
}
这最终编译(在优化版本构建中,减去mmx指令):
00021088 mov esi,dword ptr [giantVector] //move a pointer to giantVector into esi
0002108B xor eax,eax //clear out eax
000210C4 mov ecx,dword ptr [esi+eax*4] //move int from vector into ecx
000210C7 imul ecx,ecx //multiply ecx by itself
/* Move the result back into vector. This instruction uses esi as the base pointer
to the first element in the vector then adds eax(loop counter) * 4(sizeof(int))
to determine where to stick it. */
000210CA mov dword ptr [esi+eax*4],ecx //move result back into vector
000210CD inc eax //increment the loop counter in eax
000210CE cmp eax,989680h //compare with SIZE constant
000210D3 jl main+0C4h (0210C4h) //If less, jump back into loop, otherwise fall through
我在这里的评论只是我对事物的理解,我正在逐步完成这些事情。
我的问题是...... 000210CA
的指示如何运作? esi + eax * 4
不是计算本身吗?为什么该指令本身不需要其他指令来计算?或者那是真的发生了什么?在地址空间中,指令似乎是顺序的。
如果它有所帮助,则由Visual Studio 2015编译,并且此代码从反汇编调试窗口中提取。
答案 0 :(得分:3)
英特尔x86架构允许[scale*index+base]
格式的地址,其中scale
为1,2,4或8,index
和base
为寄存器(eax / EBX / ECX / EDX / ESP / EBP / ESI / EDI)。这些地址使用称为SIB字节的机器指令字节表示。当然,您不能在单个汇编指令中嵌入任意计算。