(使用Visual Studio语法汇编代码)我知道这是一个显而易见的问题,但我对汇编还是个新手。
在下面的练习中,我很难理解esi
寄存器是如何工作的:
#include <stdio.h>
int main()
{
int a = 0;
int b[5] = { 1, 2, 3, 4, 5 };
int *c;
c = &b[0];
__asm {
mov ebx, c
mov eax, dword ptr [ebx]
mov esi, 3
add eax, dword ptr [ebx+esi*4]
mov ecx, eax
mov a, ecx
}
printf("sum of first and fourth element is: %d", a);
}
我需要打印第一个和第四个元素的总和。程序的工作原理如下:
- 定义
a
和数组b
,定义指针c
,它指向b
的第一个元素。 - 将
c
移到ebx
中。[c
指向第一个元素,因此ebx
包含第一个元素] - 把指针指向的东西移到
eax
寄存器中。[它是ebx
] - 将
3
移到esi
寄存器中。[关键部分我不理解] - add运算符[我不理解关键部分]
- 移动运算符[简单的部分,没有问题]
我的问题是:
- 为什么我必须将
3
复制到esi
寄存器中? - 为什么我必须执行此操作?
[ebx+esi*4]
我知道esi
使事情变得容易得多,但是我不知道如何使用这个寄存器。
1条答案
按热度按时间vaqhlq811#
将数组
b
的第一个元素和第四个元素相加可写成:由于指针
c
被初始化为指向b
的第一个元素,因此这等效于为了将
c[3]
与包含c
值的ebx
相加,代码将esi
设置为3
并使用add eax, dword ptr [ebx+esi*4]
。此指令将从内存中读取的32位值与ebx
在索引esi
处指向的数组相加,然后直接乘以int
的大小(作为寻址模式的一部分)。如果
esi
包含某个计算的结果或参数值,这将是有用且高效的,但对于常量索引,更简单的方法是在编译时计算偏移量:还请注意,使用
ecx
来存储结果也是多余的。下面是一个简化版本:
但是请注意,目前还不清楚汇编代码是否会对
ebx
和esi
产生副作用而不产生后果...