专题:汇编语言中有符号数还是无符号数? |
一、汇编语言在存储方面讲,有符号数和无符号数存储形式是一致的。
l 数据在内存或CPU的寄存器中都是按照有符号数的二进制补码方式存储的。
例如(在debug中测试):
mov ax,-9
怎么理解这个代码?首先-9==-09H,它是16进制的(在debug中一律按照16机制存储,没有十进制,是在汇编语言中可以写十进制,编译器会给你自动处理了,在debug中不行,当然此例中也可以是十进制的,因为它们还没有差别呢)。
-09H的二进制补码是:
原码:1000 0000 0000 1001B 反码:1111 1111 1111 0110B
补码(反码+1):1111 1111 1111 0111B==FFF7H
我们在debug中查看结果:
0B04:0100 mov ax,-9
-t
AX=FFF7 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0B04 ES=0B04 SS=0B04 CS=0B04 IP=0103 NV UP EI PL NZ NA PO NC
测试结果:我们发现,在存储这个方面来说,汇编都是按照二进制补码方式存储二进制数据或指令的。
l 编译器不区分是有符号数还是无符号数。
在汇编语言的源代码中,我们可以随意设置一个数据,无论它是十六进制的还是十进制的。但是在存储层面上,它一律是按照二进制的补码方式存储的。这中间还有个编译器帮助你转换成了二进制的补码。编译器不区分是有符号数还是无符号数。
例如,汇编源代码如下:
assume cs:code
data segment
db -20 ;十进制表示,单字节,高字节截断了
db 236 ;十进制表示,单字节,高字节截断了
db 0ecH ;十六进制表示,二进制的补码
data ends
code segment
start:
mov ax, data
mov ds,ax
mov ax,4c00H
int 21H
code ends
end start
编译、连接后,debug结果:
-d ds:0
0B65:0000 EC EC EC 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
我们发现:在内存中都是以EC存储的。这个EC是?-20的补码?我们看下。
-20原码:10010100 反码:11101011B 补码:11101100B==ECH
那么236原码:11101100B 对于正数它的补码就是源码 故它的补码:11101100B==ECH
疑问?难道+236等于了-20?,关键在于存储的内存单元的大小,目前程序设定的是单字节存储这3个数据,它们都是一样的。
貌似在编译器层面上,将有符号数和无符号数这二个标准统一成一个结果。换句话说,在编译器层面上,能够识别二种标准的。其实不然,就一种标准:有符号二进制补码。产生上述的原因是由于存储单元容量小,存储不下高位的信息了,截断了高位。
但是对于2个字节存储这些数据:-20(FFECH)、236(00ECH)、ECH(00ECH)。这个就区分出来了。我们还发现了,对于二进制补码,最高位是1代表负数,0代表正数,这个符号位(最高位)在计算机的原码和补码中是一致的。其他的位是数据位。
二、在汇编程序层面上,还是要区分有符号数和无符号数的。
计算机对有符号和无符号数区分的十分清晰,因为计算机进行某些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。
一个数到底是有符号数还是无符号数,计算机并不知道,这是由程序员来决定的,当你认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,当你认为你要处理的数是无符号的,那就用处理无符号数的那一套指令。
加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx … 是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。
还有,在程序员在程序层面上区别是有符号数和无符号数,在底层CPU也可以通过flag寄存器的标志位来判断的有符号数和无符号数。
三、结论:
1)在汇编语言中。数据或代码是按照二进制补码方式存储的,无论数据是有符号数还是无符号数。那是汇编语言编译器需要干的事情,自动帮你转换了。
2)在计算机底层,我们要注意内存单元和寄存器变量所能存储的最大位数,也就是说利用补码方式存储的数据的范围;注意溢出的问题。
3)在程序员编写指令时,要考虑有符号数和无符号数,对它们使用不同的指令区分。也就是说运算的时候,可能可以选择不同的命令来指定把要操作的数据(补码形式存在)当多有符号数或是无符号数来使用。
4)对于CPU来说,只能通过flag的标志位来判断有符号数和无符号数的运算结果。
5)对于是否是有符号数还是无符号数,程序员不必太纠结,在汇编语言源程序编程这个层面上,你只要按照你所期望的使用指令就行了。