首页
社区
课程
招聘
[求助]问IMUL指令的用法
发表于: 2007-10-20 23:30 12271

[求助]问IMUL指令的用法

2007-10-20 23:30
12271
查了一下手册,看没看懂,来问问
例子:
mov cl 7
mov al D1
imul cl
执行后,eax为 FEB7,请问是怎么得出来的啊 ?

另外,如果用c实现的这样的乘法的话,该如何做:

char a,b;
a = 0xd1;
b = 7;
int c = a*b? // 这样得不出feb7, 那该如何写才能得出这个数啊?
谢谢了

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
2
前面加上or eax, -1
2007-10-21 01:00
0
雪    币: 462
活跃值: (53)
能力值: ( 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位),这也就是最终的计算结果。
2007-10-21 01:26
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼上完全正确
符号问题
汇编和c的结果一样的
2007-10-21 08:35
0
雪    币: 205
活跃值: (171)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
谢谢楼上的两位,再问一下,是否有这样的函数,进行计算:
int imul(char a, char b) // 这个函数该如何实现?
{...}
void main()
{
char a,b;
a = 0xd1;
b = 7;
int c = imul(a, b);
}
2007-10-21 14:41
0
雪    币: 424
活跃值: (10)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
6
干脆`
__asm{..}
2007-10-21 14:44
0
雪    币: 200
活跃值: (10)
能力值: ( 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);
}
2007-10-21 15:06
0
雪    币: 205
活跃值: (171)
能力值: ( 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呢

}
2007-10-21 20:06
0
雪    币: 200
活跃值: (10)
能力值: ( 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);       
}
2007-10-24 08:21
0
游客
登录 | 注册 方可回帖
返回
//