原始机器码
5=0000 0101=0x05
5=0000 0000 0000 0101=0x0005
5=0000 0000
0000 0000 0000 0000 0000 0101=0x00000005
-3=1111 1101 补码
+3=
0000 0011= byte
-3 = 1000 0011 = byte
+8= 0000 1000
- 8= 1000
1000
+0= 0000 0000
-1=1111 1111
-2=1111 1110
-3=1111
1101
255=1111 1111=0xFF
那么现在假如看到一个数1111
1111到底是十进制255,还是十进制数-1呢?
哪一个才是正确的?
答案:这是我们自己的事情,取决于我们怎么样看待它。
无论是有符号数还是无符号数,计算的结果都是正确无误的。
1000 1111
0000 0001
===========
1001 0000
当成无符号数理解相加:
10001111=0x8F=143
00000001=0x01=1
========================
10010000=0x90=144
当成有符号数理解相加:
1000
1111=1000 1110= 1111 0001 =0xF1=-113
0000 0001=0000 0001 = 0000 0001 =0x1=
1
=====================================
1001 0000=1000 1111 = 1111 0000
=0xF0=-112
拓展
neg
mov al,0x08 0000 1000
neg al 1111 1000
=F8=248
为了能够让电路简洁,不需要判断第一位是符号位,所以设计了原码补码反码,并且只需要加法电路就可以完成减法。
但为了方便,处理器还是提供了减法指令sub
sub
ah,al
相当于
neg al
add ah,al
比如
ah=5
al=3
ax = 0000 0101 0000 0011
neg
al
ax = 0000 0101 1111 1101
add
ah,al
cbw
cwd
几乎所有的指令都可以同时计算无符号数和有符号数。
但有几条指令除外。
比如除法指令和乘法指令。
div是一个除法指令
无符号数
0x0400当做十进制数是1024.
0xf0当做十进制数是240
有符号数
0x0400等于十进制1024
0xf0等于十进制的-16
结果完全不一样。
mov ax,0x0400
mov bl,0xf0
div bl
;执行后,AL中的内容为0x04,十进制的4
mov ax,0xf0c0
mov bl,0x10
idiv
bl
以上的代码是16位二进制数除法,结果在寄存器AL中。除法的结果应当是十进制数-244,
遗憾的是,这样的结果超出了寄存器AL所能表示的范围,必然因为溢出而不正确。
为此,你可能会用32位的除法来代替以前的做法:
mov
dx,0
mov ax,0xf0c0
mov bx,0x10
idiv
bl
————————————————
mov ax,0xf0c0
cwd
mov
bx,0x10
idiv bx