论文导读:在使用A命令进行行汇编时。发现四条移位指令中SAL指令不能被识别。而其余三条指令正常(如图1所示)。运算结果溢出了。
关键词:SAL,指令,行汇编,溢出
一、发现问题在DEBUG程序中,在使用A命令进行行汇编时,发现四条移位指令中SAL指令不能被识别,而其余三条指令正常(如图1所示),即DEBUG的A命令不支持这条指令。但是我们将SAL写入汇编语言源程序中(.ASM)进行编译,则不提示出错(如图2所示)。
图1
图2
为什么同样是8086指令系统中的移位指令,唯独“SAL”指令在“DEBUG”中遭到如此“不公正”的待遇呢?
二、进一步研究问题当我们将包含“SAL”指令的源程序进行编译、连接,再将生成的EXE文件用DEBUG程序的U命令进行反汇编时,发现SAL指令在编译过程中被编译程序替换为SHL指令(如图3所示),而原来的“SHL”指令却没有变。
图3
三、思考问题,寻求答案1.关于SAL指令和SHL指令SAL指令是8086汇编语言中的移位指令。8086汇编语言中的移位指令分为算术移位指令和逻辑移位指令。算术移位是对带符号数进行移位操作,在移位过程中必须保持符号不变;而逻辑移位是对无符号数进行移位操作,总是用“0”来填补已空出的位。而8086汇编语言中的移位指令共有四条,分别是:算术左移指令SAL,算术右移指令SAR,逻辑左移指令SHL和逻辑右移指令SHR。
为什么8086汇编程序的编译器会将算术左移替换为逻辑左移呢?
2.移位的实质我们都知道,对于一个二进制数来说,左移1位相当于将这个数乘以2,右移1位相当于将这个数除以2。而在计算机中,数一般都是以补码的形式存储的。这样一来,对于有符号数,移位(左移或右移)就可能会造成其符号位的改变。在移位指令中分算术移位指令和逻辑移位指令的目的也在于此。发表论文。在算术移位中,要求保证被移位数的符号位不变,对于右移指令,移位时用符号位的值对空出来的符号位进行填充即可保证符号位的值不发生变化;而左移指令在执行时,只能用最高数值位对符号位进行填充,这样一来,就不能保证不让符号位发生变化了。发表论文。实际情况是怎样的呢?我们用一些实例来说明这个问题。
(1)正数的向左移位
( 1) 补 =00000001Bà(左移1位)à00000010 B =(2) 补 ( 2) 补 =00000010B à(左移1位)à00000100 B =(4) 补 ( 4) 补 =00000100B à(左移1位)à00000100 B =(8) 补 ( 8) 补 =00001000B à(左移1位)à00001000 B =(16) 补 (16) 补 =00010000B à(左移1位)à00010000 B =(32) 补 (32) 补 =00100000B à(左移1位)à00100000 B =(64) 补 (64) 补 =0 1000000 B à(左移1位)à10000000 B =(-128) 补 符号位 最高数值位
从上面的移位结果来看,只有当最高数值位上为1(其真值大于等于64)时,向左移位才会导致符号位发生变化。而对于一个不小于64的数,其乘以2的结果至少为128,已经超过8位二进制有符号数所能表示的最大范围(-128~+127)了,运算结果溢出了。也就是说,只要运算结果不溢出,就可以保证移位后的符号位不发生变化,也就可以保证移位的正确性了。
(2)负数的向左移位
(- 1) 补 =11111111B à(左移)à11111110 B =(-2) 补 (- 2) 补 =11111110B à(左移)à11111100 B =(-4) 补 (- 4) 补 =11111100B à(左移)à11111000 B =(-8) 补 (- 8) 补 =11111000B à(左移)à11110000 B =(-16) 补 (- 16) 补 =11110000B à(左移)à11100000 B =(-32) 补 (- 32) 补 =11100000B à(左移)à11000000 B =(-64) 补 (- 64) 补 =11000000B à(左移)à10000000 B =(-128) 补 (-128) 补 =1 0000000 B à(左移)à00000000 B =(0) 补 符号位 最高数值位
从上面的移位结果来看,只有当最高数值位上为0(其真值小于-64)时,向左移位才会导致符号位发生变化。而对于一个小于-64的数,其乘以2的结果最大超不过-128,已经超过8位二进制有符号数所能表示的最大范围(-128~+127)了,运算结果溢出了。也就是说,只要运算结果不溢出,就可以保证移位后的符号位不发生变化,也就可以保证移位的正确性了。
从上面的对于正、负二进制数的移位结果来看,只要乘以2后不溢出的数,向左移位都可以保证其符号位的值不改变。所以,完全可以将用逻辑左移替代算术左移。
四、结论及意义综上所述:无论是正数还是负数,只要是乘以2后不溢出的数,向左移位都可以保证其符号位的值不改变(而移位后溢出的数,其符号位必定会发生改变)。发表论文。所以,在进行左移操作时,可以不考虑逻辑移位和算术移位的区别。
而我们都知道,指令系统和硬件是密切相关的,每一条指令都对应着相应的硬件实现。指令越复杂,硬件实现越困难;同样,指令数量越多,硬件也越难以实现。所以,在不影响系统功能的情况下,减少一条指令(用其它的指令替代)不但能简化机器的硬件结构,还可以提高硬件的集成度,是硬件设计者和制造商都乐意而为之的;对用户的使用是没有影响的。虽然我们看到的现象是在“DEBUG”中,SAL指令不能被识别;在汇编过程中,用SHL指令替换SAL指令,但是这样做是有意义的。故笔者认为,在8086汇编语言的编译过程中,使用SHL指令替换SAL指令不但是可取的,而且是提高效率的一种做法。
参考文献:
[1]李继灿.《新编16/32位微型计算机原理及应用》[M].北京:清华大学出版社,2004.1.
[2]沈美明,温冬婵.《IBM-PC汇编语言程序设计 第2版》[M].北京:清华大学出版社,2001.8.
|