无符号和有符号的乘法口诀表指令有什么不同,例3.44的无符号乘法口诀表是怎么做的?

 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
微机原理及接口技术微机原理第03章3
下载积分:600
内容提示:精品文档: 微机原理与接口技术 微机原理及接口技术 微机原..
文档格式:PDF|
浏览次数:1|
上传日期: 23:31:54|
文档星级:
该用户还上传了这些文档
下载文档:微机原理及接口技术微机原理第03章3.PDF
官方公共微信编程语言_我还是搞不清指令本身是如何区分有符号数和无符号数!(问题汇总)_软件世界网
我还是搞不清指令本身是如何区分有符号数和无符号数!(问题汇总)
论坛的一个CSDN提问,对各方面的回答进行了汇总,答案还算比较清楚的。
一般好像是有专门的有符号数指令和无符号数指令
无符号除法是&div
有符号除法是&idiv
mov&al,27h
mov&bl,73h
如果是无符号数al的结果为A),如果是有符号数结果是什么?
&&&&如果是有符号数,结果依然是A)。注意,此时溢出标志置位。表明这个加法如果是作为有符号数的加法时,结果是不能用的。当然,如果你把这个加法作为无符号数的加法来看,结果则是可用的(虽然此时仍有溢出,但它是无意义的。溢出只针对有符号数而言的)。
&&&&这是个特例。因为无符号数的加减法与有符号数的补码的加减法是恰巧是一致的。因此有符号数与无符号数可以使用同一指令,得到同一结果。而这一结果是作为有符号数还是无符号数,是由程序员来定义的:如果程序员认为是有符号数的加减法,则他将关心运算结果的溢出标志,以判别结果是否可用;如果程序员认为是无符号数的加减法,则他将关心运算结果的进位标志,看运算结果是否有进(借)位。
&&&&正是基于这样的原因,计算机的有符号数才采用补码表示。
上面不是跟你说的很清楚了吗?由于无符号数的加法与有符号数(补码)的加法是一致的,因此完全没有必要去区分指令的操作数是有符号数还是无符号数。关键在于运算结果你自己如何看待。
  al=C),bl=(E7),则
  add&al,bl 
  运算结果是:
  al=)&且进位标志CY=1,溢出标志OV=0.
  对于这个结果,你可以把它作为无符号数运算,即有:
  al=9Ch=156d,bl=E7h=231d,运算结果al=83h=131d,考虑到进位,运算结果应为131+256=387,而al+bl=156+231=387.正确。
  同样对于这个结果,你也可以把它作为有符号数的运算,即有:
  al=9Ch=-100d,bl=E7h=-25d,(注意有符号数均看成补码,9Ch是-100的补码,下同)。
  而运算结果al=83h=&-125d,因为没有溢出(有符号数是不考虑进位的),运算结果可用。
  而al+bl=9Ch+E7h=(-100)+(-25)=-125.可见结果亦完全正确。
  由上例可见,无符号数的加法与有符号数的补码加法是完全一致的。CPU没有必要去区分。关键在于程序员如何去看待。CPU的运算结果将同时影响进位标志与溢出标志。如果程序员认为这是无符号数运算,则只考虑进位标志而忽略溢出标志。反之,如果程序员认为这是有符号数运算,则只考虑溢出标志而忽略进位标志。
指令本身不区分操作数的类型。
指令的操作格式是固定的,并对应一个操作码。
在&C&下,应该是由编译器根据你定义的数据类型使用不同的指令。
汇编下,你应该去选择使用那类指令。
无符号数的加法与有符号数的补码加法是完全一致的。CPU没有必要去区分。关键在于程序员如何去看待。CPU的运算结果将同时影响进位标志与溢出标志。如果程序员认为这是无符号数运算,则只考虑进位标志而忽略溢出标志。反之,如果程序员认为这是有符号数运算,则只考虑溢出标志而忽略进位标志。
高级语言,如c语言有符号数和无符号数在内存的储存上没什么不同
关键是处理数的指令,如果你声明的是有符号数,编译器在编译时就用有符号数的机器指令
反之就用无符号数的机器指令
而汇编语言中这些就要你自己来做了
总结一下,想了半天。
同意zhukeke(zhukeke)的:&&有符号数与无符号数从静态的二进制来看,是无区别的。指令之所以能区别,则是指令的设计者总是事先规定它的操作数的类型。&
但有些指令除外,象add这条,有符号数与无符号数公用,都会影响CF,OF,OF,ZF,PF.CPU统一对待.在于你怎么看待.
2.关于add指令:
(基于:(1)运算器(加法器)只有一个逻辑,无论什么运算都一样.(2)存储字长的有限.)
既然add指令有符号数与无符号数公用,都会影响CF,OF,OF,ZF,PF.为什么无符号数关心CF位,有符号数关心OF位??这其实是有符号数的表示方法即补码惹的&祸&.无符号数在字长不够时,可用CF位来寄存一位,从而解决不够问题.而有符号数确不能简单利用CF位.因为负数的补码的表示问题.
比如:al=B与bl=B.当add&al,bl时.CF=1,OF=1.表示进位,溢出.
==看成无符号数,当然也是进位,溢出了.但无符号数只需利用CF位即可修正:.因为结果在16位表示为11111,32位为&,总之高位为0,用和进位位就能表示正确结果(CF+al),所以大家只关心CF位了.OF位不关心了!
==看成有符号数,当然也是进位,溢出了.但有符号数不能简单利用CF位修正.实际上不好修正.因为结果为al(-1)+bl(-128)=al(-129)&-129的补码表示在16位为:11111.在32位为:1.总之,高位全为1.用CF位无法修正.位数不够.有人说高位全置1,不就OK??可al只有8位啊,所以光用CF+al是不行的.所以只能说它溢出了.不能用这个结果了.所以只关心OF位了.
站在计算机组成的角度,这个问题是不存的:指令是由硬件电路识别(译码)完成的,详细的解释见组成原理。这一层是在微命令层次完成的,不能完成微命令的“码”就是地址码!(IBM),而地址码是指明数据位置的或计数的
如果是用汇编者眼光分析,问题在于你的指令已经识别出来------指令池中有这些“硬件库”。其它的“码”均视为数据(内存中的单元的地址或一个数据),它的构造由你程序决定:有符号还是没符号。这里还是要从组成原理角度才能说清。
如果你使用的是高级语言,则几乎没有必要对它进行讨论,因为指令在高级语言(如C)中是透明的。
&此文从网络中自动搜索生成,不代表本网站赞成被搜索网站的内容或立场
软件世界网- &2014 蜀ICP备号 三峰网旗下网站如何用十六位乘法指令完成三十二位无符号数乘法(结果64位)高手请进。。。急!!!!!!!!!!!_百度知道
如何用十六位乘法指令完成三十二位无符号数乘法(结果64位)高手请进。。。急!!!!!!!!!!!
使用MUl指令,完成双字无符号数乘法程序,要求乘数和被乘数从键盘输入,结果显示于屏幕上
我有更好的答案
怎么无人回答啊?同求啊!找了好久找到一个类似的:4. 无符号整数乘法,乘数为32bit,结果为64bit提示:32bit整数分解为16bit相乘void Multiply( DWORD dwFirst, DWORD dwSecond, DWORD& dwHigh, DWORD& dwLower );void Multiply( DWORD dwFirst, DWORD dwSecond, DWORD& dwHigh, DWORD& dwLower ){
DWORD ah,al,bh,bl
ah = dwFirst&&16;
al = dwFirst&0
bh = dwSecond&&16;
bl = dwSecond&0
dwHigh = ah*
dwLower = al*
DWORD tmp1 = ah*
DWORD tmp2 = al*
dwHigh += tmp1&&16;
dwHigh += tmp2&&16;
DWORD tmp3 = (tmp1&0xffff) + (tmp2&0xffff) + (dwLower&&16);
dwHigh += tmp3&&16;
dwLower &= 0
dwLower |= (tmp3&0xffff)&&16;}
其他类似问题
无符号数的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁有符号数,无符号数,补码,溢出
1、加减运算指令是不区分有符号和无符号的,编程人员自己要心理有数。
说清这个问题,需要理解几个概念:
1. CF 进位标志位 Carry Flag
反映运算是否产生进位或者借位的操作,如果运算结果的最高位产生了一个进位或错位,那么,其值为1,否则为0。
2. OF 溢出标志 Overflow Flag
溢出标志OF用于反映有符号数
加减运算所得结果是否溢出,如果运算结果超过当前运算位数所能表示的范围,则成为溢出,OF的值被设置为1,否则OF的值被清为0。
溢出和进位是两个不同的概念 。
3.在PC系统中,有符号数用补码表示. 正数的补码是其本身,负数的补码是其对应正数取反加一,
补码表示,使得加减法统一了起来。
4. pc 中正负数是靠最高为来判断的,最高为就等于SF, (sf=0 为正, sf=1为负)
5. 给定一个数,如果你认为它是正数,要用CF 判断溢出。 判断大小也用CF
& 如果你认为它是负数,要用OF 判断溢出。 判断大小也用要用OF,SF配合使用。
具体怎么配合这就不说了
CPU只会根据输入信号进行逻辑运算,在硬件级别是没有有符号无符号的概念,运算结束会根据运算前的信号和输出信号来设置一些标志位,是不是有符号由写程
序的人决定,标志位要看你把操作数当有符号还是无符号来选择,就像内存中的数据,你可以按照需要来解析,原始数据在那里,你要按什么数据格式来解析在于自
己的选择,所以玩汇编的要做到心里有数
关于有符号数和无符号数,LZ看看这个吧:
&有符号数和无符号数探讨 &
这个问题,要是简单的理解,是很容易的,不过要是考虑的深了,还真有些东西呢。
下面我就把这个东西尽量的扩展一点,深入一点和大家说说。
一、只有一个标准!
在 汇编语言层面,声明变量的时候,没有 signed 和 unsignde
之分,汇编器统统,将你输入的整数字面量当作有符号数处理成补码存入到计算机中,只有这一个标准!汇编器不会区分有符号还是无符号然后用两个标准来处理,
它统统当作有符号的!并且统统汇编成补码!也就是说,db -20 汇编后为:EC ,而 db 236 汇编后也为 EC
。这里有一个小问题,思考深入的朋友会发现,db 是分配一个字节,那么一个字节能表示的有符号整数范围是:-128 ~ +127 ,那么
db 236 超过了这一范围,怎么可以?是的,+236
的补码的确超出了一个字节的表示范围,那么拿两个字节(当然更多的字节更好了)是可以装下的,应为:00 EC,也就是说
+236的补码应该是00 EC,一个字节装不下,但是,别忘了“截断”这个概念,就是说最后汇编的结果被截断了,00 EC
是两个字节,被截断成 EC ,所以,这是个“美丽的错误”,为什么这么说?因为,当你把 236 当作无符号数时,它汇编后的结果正好也是
,这下皆大欢喜了,虽然汇编器只用一个标准来处理,但是借用了“截断”这个美丽的错误后,得到的结果是符合两个标准的!也就是说,给你一个字节,你想输入
有符号的数,比如 -20 那么汇编后的结果是符合有符号数的;如果你输入 236
那么你肯定当作无符号数来处理了(因为236不在一个字节能表示的有符号数的范围内啊),得到的结果是符合无符号数的。于是给大家一个错觉:汇编器有两套
标准,会区分有符号和无符号,然后分别汇编。其实,你们被骗了。:-)
二、存在两套指令!
第一点说明汇编器只用
一个方法把整数字面量汇编成真正的机器数。但并不是说计算机不区分有符号数和无符号数,相反,计算机对有符号和无符号数区分的十分清晰,因为计算机进行某
些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。但是,这里要强调一点,一个数到底是有符号数还是无符号数,计算机并不知
道,这是由你来决定的,当你认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,当你认为你要处理的数是无符号的,那就用处理无符号数的那
一套指令。加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx …
是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。
举例来说:
内存里有 一个字节x 为:0x EC ,一个字节 y 为:0x 02 。当把x,y当作有符号数来看时,x = -20 ,y = +2
。当作无符号数看时,x = 236 ,y = 2 。下面进行加运算,用 add 指令,得到的结果为:0x EE ,那么这个 0x EE
当作有符号数就是:-18 ,无符号数就是 238 。所以,add
一个指令可以适用有符号和无符号两种情况。(呵呵,其实为什么要补码啊,就是为了这个呗,:-))
乘法运算就不行了,必须用两套指令,有符号的情况下用imul 得到的结果是:0x FF D8 就是 -40 。无符号的情况下用 mul
,得到:0x 01 D8 就是 472 。(参看文后附录2例程)
三、可爱又可怕的c语言。
为 什么又扯到 c 了?因为大多数遇到有符号还是无符号问题的朋友,都是c里面的 signed 和 unsigned
声明引起的,那为什么开头是从汇编讲起呢?因为我们现在用的c编译器,无论gcc 也好,vc6 的cl
也好,都是将c语言代码编译成汇编语言代码,然后再用汇编器汇编成机器码的。搞清楚了汇编,就相当于从根本上明白了c,而且,用机器的思维去考虑问题,必
须用汇编。(我一般遇到什么奇怪的c语言的问题都是把它编译成汇编来看。)
C 是可爱的,因为c符合kiss
原则,对机器的抽象程度刚刚好,让我们即提高了思维层面(比汇编的机器层面人性化多了),又不至于离机器太远(像c#
,java之类就太远了)。当初K&R 版的c就是高级一点的汇编……:-)
C又是可怕的,因为它把机器层面的所有的东西都反应了出来,像这个有没有符号的问题就是一例(java就不存在这个问题,因为它被设计成所有的整数都是有符号的)。为了说明它的可怕特举一例:
&stdio.h&&
&string.h&&
int main()
& int x = 2;&
& char * str = "abcd";&
& int y = (x - strlen(str) ) / 2;
& printf("%d\n",y);
结果应该是 -1 但是却得到: 。为什么?因为strlen的返回值,类型是size_t,也就是unsigned
int ,与 int 混合计算时有符号类型被自动转换成了无符号类型,结果自然出乎意料。。。
观察编译后的代码,除法指令为 div ,意味无符号除法。
解决办法就是强制转换,变成 int y = (int)(x - strlen(str) ) / 2;
强制向有符号方向转换(编译器默认正好相反),这样一来,除法指令编译成 idiv 了。
我 们知道,就是同样状态的两个内存单位,用有符号处理指令 imul ,idiv 等得到的结果,与用
无符号处理指令mul,div等得到的结果,是截然不同的!所以牵扯到有符号无符号计算的问题,特别是存在讨厌的自动转换时,要倍加小心!(这里自动转换
时,无论gcc还是cl都不提示!!!)
为了避免这些错误,建议,凡是在运算的时候,确保你的变量都是 signed 的。
四、c的做法。
对 于有符号和无符号的处理上,c语言层面做的更“人性化”一些。比如在声明变量的时候,c 有signed 和 unsigned
前缀来区别,而汇编呢,没有任何区别,把握全在你自己,比如:你想在一个字节中输入一个有符号数,那么这个数就别超过 -128 ~ +127
,想输入无符号数,要保证数值在 0~255 之间。如果你输入了 236
,你还要说你输入的是有符号数,那么你肯定错了,因为有符号数236至少要两个字节来存放(为00
EC),不要小看了那一个字节的00,在有符号乘法下,两个字节的00 EC 与
一个字节的EC,在与同样一个数相乘时,得到的结果是截然不同的!!!
我们来看下具体的列子(用vc6的cl编译器生成):
C语言 编译后生产的汇编语言&
& y = 236;
& z = x*y;
& …… ……
& _x$ = -4
& _y$ = -8
& _z$ = -12
& mov BYTE PTR _x$[ebp], 3
& mov BYTE PTR _y$[ebp], 236
& movsx eax, BYTE PTR _x$[ebp]
& mov ecx, DWORD PTR _y$[ebp]
& and ecx, 255&
& imul eax, ecx
& mov DWORD PTR _z$[ebp], eax
们看到,在赋值的时候(绿色部分),汇编后与本文第一条论述相同,是否有符号把握全在自己,c比汇编做的更好这一点没有得到体现,这也可以理解,因为c最
终要被编译成汇编,汇编没有在变量声明时区分有无符号这一功能,自然,c也没有办法。但既然c提供了signed和unsigned声明,汇编后,肯定有
代码体现这一点,表格里的红色部分就是。对有符号数x他进行了符号扩展,对无符号y进行了零扩展。这里为了举例的方便,进行了有符号数和无符号数的混合运
算,实际编程中要避免这种情况。
1.计算机对有符号整数的表示只
采取一套编码方式,不存在正数用原码,负数用补码这用两套编码之说,大多数计算机内部的有符号整数都是用补码,就是说无论正负,这个计算机内部只用补码来
编码!!!只不过正数和0的补码跟他原码在形式上相同,负数的补码在形式上与其绝对值的原码取反加一相同。
2. 两套乘法指令结果例程:
;; 程序存储为 x.s
extern printf&
global main&
section .data
& str1: db
"%x",0x0d,0x0a,0&
& n: db 0x02
section .text&
& xor eax,eax
& mov al, 0xec
& mul byte [n] ;有符号乘法指令为: imul
& push eax
& push str1
& call printf&
& add esp,byte 4&
编译步骤:
1. nasm -felf x.s&
2. gcc x.o
ubuntu7.04 下用nasm和gcc编译通过。结果符合文章所述。
二、有符号数运算时的溢出
&&&&&如果计算机的字长为n位,n位二进制数的最高位为符号位。其余n-1位为数值位,采用补码表示法时,可表示的数X的范围是
&&&&&&&&&&&&&&&&&&&&&&
当n=8时,可表示的有符号数的范围为-128~+127;当n=16时,可表示的有符号数的范围为
-32768~+32767。两个有符号数进行加减运算时,如果运算结果超过可表示的有符号数的范围时,就会发生溢出,使计算机结果出错。很显然,溢出只
能出现在两个同号数相加或两个异号数相减的情况。具体的讲,对于加运算,如果次高位(数值部分最高位)形成进位加入最高位,而最高位(符号位)相加(包括
次高位的进位)却没有进位输出时;或者反过来,次高位没有进位加入最高位,但最高位却有进位输出时,都将发生溢出。因为这两种情况分别是:两正数相加,结
果超出了范围,形式上变成了负数;两负数相加,结果超出了范围,形式上变成了正数 。
&&&&&&&&&&&&例&&&&&&&&&&&&例
&&&&对于减运算,当次高位不需从最高位借位,但最高位却需借位(整数减负数,差超
出范围);或者反过来,次高位需从最高位借位,但最高位不需借位(负数减整数,差 超出范围),也会出现溢出。
&&&&&&&&&&&&例
&&&&&&&&&&&&例
&&&&综合以上是否溢出的判断:最高位的进位位次高位的进位位=1,则OF被置1。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。汇编中有符号与无符号数的区分_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
21页免费8页1下载券5页免费9页免费4页免费 27页免费11页1下载券12页免费8页免费7页免费
喜欢此文档的还喜欢17页免费3页免费19页免费2页免费1页免费
汇编中有符号与无符号数的区分|汇​编​中​有​符​号​与​无​符​号​数​的​区​分
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢

我要回帖

更多关于 乘法指令 的文章

 

随机推荐