020-【X86-汇编语言】-有符号数?无符号数?

在介绍标志位时提到了【进位标志位(CY)】和【溢出标志位(OV)】。有的同学可能会疑惑计算机是如何知道当前的数字是有符号数还是无符号数。今天就这个问题详细介绍一下

符号的由来

计算机本质上是复杂的数字电路,其主要工作是对输入的电信号做处理,产生输出电信号。从实用性和设计成本考虑在设计数字电路时只设计了两种状态--高电位和低电位。不同的芯片的高低电位的分界电压是不同的。比如有以5V为分界电压的,电压高于5V视为高电位,低于5V的视为低电位。也有3V的、2.8V的、1.2V的。通常来说分界电压越高的抗干扰性越强,电压越低的效率越高且节能。

人类利用计算机时,只是将电信号输入给计算机,并获取计算机输出的电信号。因为数字电路的信号只有两种状态所以人类使用二进制数与其对应,高电位对应1,低电位对应0。关于二进制数可以回顾003-【X86-汇编语言】-绕不开的二进制

由此我们可以知道计算机的眼里没有数字只有信号,而是我们人类人为地将二进制数对应的到了计算机的电信号上。

因为在现实生活中数字有【负】有【正】,而计算机只识高低电位,因此在表示正负数的时候就需要专门用一位二进制数来表示数字的符号,这就是有符号数。又因为在某些情况下我们用不到负数,不需要专门用一位二进制数表示数字的符号了(默认数字都是正号,这样可以用同样的位数表示更大范围的正数值),这就是无符号数。关于有符号数和无符号数可以回顾004-【X86-汇编语言】-信息的形式&整数

无符号和有符号的统一

由上一段得知,计算机是没有【数】的概念的,也就更没法区分【有符号数】和【无符号数】了。那么计算机如何运算呢?比如如何计算【3-2】和【3+2】。为解决这个问题科学家们设计了一种叫补码的数字表示法使得正负数的计算得以统一。用了补码计算机的数字电路只需要实现两种操作便可以对正负数进行计算了,一种操作是求补码(NEG),另一种操作是加法(ADD)。关于补码可以回顾005-【X86-汇编语言】-二进制整数的加减乘除&补码

程序演示

下面我们通过程序演示【1-1】和【1+255】来直观了解无符号数和有符号数的统一,程序中使用的都是BYTE(8为bit)类型

实例1

分析:

  • 1-1可以视为1+(-1),因此计算1-1需要进行两步运算,先求出-1的补码,再用1的补码加上(-1)的补码
  • 1可以是有符号数也可以是无符号数,其补码是00000001b
  • -1是有符号数,其补码11111111b
  • 255是无符号数,其补码为11111111b(与-1一样)

那么对于计算机来说 1+(-1)和1+255是一样的,都是00000001b + 11111111b

程序:

.386
.model flat,stdcall
.stack 4096
 
ExitProcess PROTO,dwExistCode:DWORD
 
.data
X1 SBYTE 1d  ;声明变量X1为有符号数1,补码为00000001b
X2 BYTE 255d ;声明变量X2为无符号数255,补码为11111111b
.code
MAIN PROC
MOV EAX,0h	;清空EAX
MOV AL,1d	;将AL赋值成1,补码为00000001b
NEG X1		;计算X1的补码,补码为11111111b
ADD AL,X1	;计算1+(-1)
MOV AL,1d	;将AL赋值成1,补码为00000001b
ADD AL,X2	;计算1+255
INVOKE ExitProcess,0
MAIN ENDP
END MAIN

总结:

当执行【ADD AL,X1】时我们发现AL的值变成0,根据实际情况判断的确符合1+(-1)的结果。同时我们发现溢出标志位【OV】的值为0,因为1+(-1)的计算结果并没有超出有符号数BTYE的表示范围([-128,127]),【OV】=0符合计算结果。但是我们发现进位标志位【CY】的值却为1。这是因为00000001b+11111111b超出了无符号数的表达范围([0,255]),所以CY=1。由此我们可以看出计算机并没有区分-1是有符号数还是无符号数,而是仅仅依照二进制数加法法则进行计算,并且设置对应的标志位。

执行【ADD AL,X2】的结果与执行【ADD AL,X1】的结果完全一致,认证了计算机是不区分有符号和无符号数的。

我们在利用计算机进行计算的时候,需要根据自己的需要获取不同标志位的值来判断计算结果是否超出范围。如果我们认为是有符号数的计算就要重点关注【OV】的值,如果我们认为是无符号数的计算就要关注【CY】的值

SUB指令有何用?

由上面可以看出1-1可以,视为1+(-1),那是不是说SUB指令就没有用处了呢?或者说只是简化了程序输入。

同学们可以自己做实验观察一下,将程序中【NEG X1】【ADD AL,X1】两条指令,改成一条【SUB AL,X1】后计算结果有何变化,主要关注各标志位的变化

猜你喜欢

转载自blog.csdn.net/patronwa/article/details/88835969