我正试图抓住集会,但有一件事可能非常简单,我不明白。
考虑以下简单示例
long long * values = new long long[2];
values[0] = 10;
values[1] = 20;
int j = -1;
values[j+2] = 15; // xxxxxxx
现在,最后一行(标有xxxxxx)反汇编为:
000A6604 mov eax,dword ptr [j]
000A6607 mov ecx,dword ptr [values]
000A660A mov dword ptr [ecx+eax*8+10h],0Fh
第一个问题:实际存储在eax和ecx中的是实际值(即“j”为-1,“值”为两个长long值10和20),还是仅仅是一个内存地址(例如某些像& p,& values)指向存储值的某个地方?
第二个问题,我知道第三行应该做什么,但我不太确定为什么这实际上有效。 所以我的理解是,它将值0x0F复制到指定的内存位置。内存位置基本上是 - 存储在ecx中的第一个元素的位置 - 加上long long的大小(以字节为单位)(= 8)* eax的值(等于j,所以-1) - 加上16字节的通用偏移量(长度的2倍)。 我没有得到的是:在这个表达式中,ecx似乎是一个内存地址,而eax似乎是一个值(-1)。这怎么可能?看到它们的定义方式几乎相同,eax和ecx不应该都包含内存地址,还是两个值?
感谢。
答案 0 :(得分:2)
eax
和ecx
是寄存器 - 前两个指令使用计算中使用的值加载这些寄存器,即j
和values
(其中{{1} “}表示该名称的数组的基址。
我知道第三行应该做什么,但我不太确定为什么这实际上有效
指令values
表示将值0Fh(即15十进制)移动到位置mov dword ptr [ecx+eax*8+10h],0Fh
。为了弄清楚这一点,请考虑每件事:
ecx+eax*8+10h
是ecx
数组的基地址
values
是eax
的值,即-1
j
被eax*8
转换为以字节为单位的偏移量 - j
的大小为8字节
long long
10h是16位小数,即2 * 8,所以这是eax*8+10h
转换为字节偏移量
j+2
将最终偏移量添加到数组的基地址,以确定存储值的位置15