能力值:
(RANK:1060 )
|
-
-
2 楼
前面加上or eax, -1
|
能力值:
( LV9,RANK:460 )
|
-
-
3 楼
首先说一下,用汇编和C得出的结果是完全一致的。最后AX中都是0xFEB7,楼主说EAX中是此值,应该是笔误,这牵涉不到EAX。
接下来说符号数乘法的问题:
如果你仔细看Intel指令手册就会知道,处理器中涉及到符号数的运算都是以补码进行的(详细情况可以参考Intel指令手册2006年11月版第一卷4-4页最后一段话第二行)。下面分析运算过程:
MOV CL, 7
MOV AL, 0D1H
两条指令执行之后,CL中的值是0x07,AL中是0xD1。当执行IMUL指令时,CPU查看这两个数的符号位,CL是0(0x07=00000111B)而AL是1(0xD1=11010001B)。一正一负,结果一定是负,CPU将其记下。然后进行正常的补码运算。我在这里不说如何直接进行补码运算,我将其还原成相应的原码的绝对值来进行(不讨论符号了)。0x07的原码的绝对值是其本身,0xD1的原码的绝对值是00101111=0x2F,0x07*0x2F=0x149=101001001B,此时AL!=AX,故CF和OF都被置位。由于CPU中都是以补码形式存在的,所以我们手工计算的结果0x149需要被转换成它的补码。因为它的符号位为1(一正一负得负),故最后求得的补码为1111111010110111=0xFEB7(由于结果被保存在AX中,故将其扩展到16位),这也就是最终的计算结果。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
楼上完全正确
符号问题
汇编和c的结果一样的
|
能力值:
( LV4,RANK:50 )
|
-
-
5 楼
谢谢楼上的两位,再问一下,是否有这样的函数,进行计算:
int imul(char a, char b) // 这个函数该如何实现?
{...}
void main()
{
char a,b;
a = 0xd1;
b = 7;
int c = imul(a, b);
}
|
能力值:
( LV9,RANK:850 )
|
-
-
6 楼
干脆`
__asm{..}
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
#include <stdio.h>
int imul(char a, char b)
{
int c;
c = a * b;
return c;
}
void main()
{
int c;
c = imul(0xD1, 0x7);
printf("%x", c);
}
|
能力值:
( LV4,RANK:50 )
|
-
-
8 楼
不好意思了,好像还是不太明白
干脆我把代码贴出来吧
void main()
{
char a,b,d;
int c;
a = 0xD1;
b = 0x07;
d = a/b; //这里结果为 -6 汇编:idiv 得到为: 1D, 这里我们才能得到1D呢
c = a*b; //这里结果为 -329 汇编:imul 得到为:FEB7 这里我们才能得到FEB7呢
}
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
void main()
{
char a,b,d;
int c;
a = 0xD1;
b = 0x07;
d = a/b; //这里结果为 -6 汇编:idiv 得到为: 1D, 这里我们才能得到1D呢
c = a*b; //这里结果为 -329 汇编:imul 得到为:FEB7 这里我们才能得到FEB7呢
// 改用下面的即可
d = (unsigned char)a/b;
c = (unsigned short)(a*b);
}
|
|
|