执行该指令之前,EDX的值为21,进位标志为0。
按下F7键,EDX减去3,然后减去进位标志0。
现在,将进位标志修改为1,然后重复上面的操作。
按下F7键,EDX减去3,然后减去进位标志1。
26
这种情况,结果为1D。 MUL(无符号数的乘法)
有两种乘法,第一个种是MUL,这种是无符号数乘法,只有一个操作数,另一个操作数是EAX,结果存放到EDX:EAX中。 例如:
MUL ECX
这里是无符号数EAX,ECX相乘,结果存放到EDX:EAX中。 OD中来看下面的例子:
我将EAX设置为了FFFFFFF7,ECX设置为了9,使用Windows自带的计算器计算的结果如下:
27
结果为:
EAX的值不变,按下F7键,在OD中我们来看看会发生什么。
由于EDX和EAX的值改变了,所以以红色突出显示,而且,我们可以看到,一部分保存在EAX
28
中,另一部分保存在EDX中,EAX容纳不下高位的8,所以存放到EDX中了,所以我们说结果存放到EDX:EAX中,也就是说,大小是单个寄存器的两倍。 下面的情况:
MUL DWORD PTR DS:[405000]
两个无符号数,405000内存单元中的值乘以EAX,结果跟之前的一样,存放到EDX:EAX中。 要在OD中查看一个数字的无符号16进制值的话,可以在任意通用寄存器上面双击鼠标左键。
第二行可以看到有符号数的值(有符号值为-81),但是MUL这样的指令,操作数都是无符号的。第三行包含了无符号的十进制值。我们可以看到是4294967215,是一个无符号数。 IMUL(有符号数的乘法)
IMUL指令用法类似于MUL。 IMUL ECX
该指令将有有符号数ECX乘以EAX,结果存放到EDX:EAX中。
除了上面一条指令外,IMUL还允许使用多个操作数,这是与MUL不同的地方。 补充:
尽管在默认情况下是使用EAX和EDX寄存器,但是我们还可以指定其他的数据源以及目标多达三个操作数。第一个操作数,用来乘以两个数,并且保存相乘的结果,结果必须保存在寄存器中。下面我们将看到两个和三个操作数的例子。 F7EB IMUL EBX EAX x EBX -> EDX:EAX 这是第一个例子,类似于MUL,但是是有符号的乘法。
696E74020080FF IMUL EBP, DWORD PTR [ESI+74],FF800002 [ESI+74] x FF800002 -> EBP
这是第二个例子,其中有三个操作数: ESI+74内存单元的值乘以FF800002,并且将结果存储到EBP中。我们可以在OD中执行看看。
把IMUL EBP, DWORD PTR [ESI+74], FF800002拷贝到OD中。
当我们按下Assemble按钮的时候会提示错误,因为在OD中,数字开头不能为字符,我们可以在开头添加0来解决这个问题。
29
现在按下Assemble按钮就不会提示错误了。
为了确保能够读取ESI+74这个地址的值,我们将ESI的值修改为401000。
见注释:
这里表示ESI+74的值为401074,该内存单元中的值为C7000000。在数据窗口中查看一下。
这里,ESP+74是指向401074这个地址,里面存放的值为C7000000。乘以FF800002,结果存放到EBP中。
IMUL EBP, DWORD PTR [ESI+74], FF800002
按下F7键,可以看到EBP变成红色了,相乘的结果存放在其中。
在计算器中我们计算C7000000*FF800002的结果如下:
30