负数

原始机器码

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

原文地址:https://www.cnblogs.com/xiaodaxiaonao/p/7218557.html