首页 > 代码库 > 汇编基础:二进制和十六进制
汇编基础:二进制和十六进制
理解二进制和十六进制的最佳方法是先透彻的领悟十进制计数系统。十进制(Decimal)系统是基于10的计数系统(词根Deci-表示10)。“基于10”指的是由10个数位(Digit)0到9来表示数。
使用“位置(Place Value)”,可以用不多的几个数位(如10个十进制数位)来表示很大的数。所有计数系统的位置从最右边开始,是基数的0次幂。从右往左,基数的幂依次增加1:
X4X3X2X1X0
基数是10时,前5个位值是: 104103102101100
对任何基数,前两个位值是最容易计算的。任何数的0次幂是1,所以100=1。任何数的1次幂就是它本身,所以101 = 10。第三个位值也是容易计算的,只要简单地用第二个位值乘以基数就可以。事实上,每一个位值都可以用它前面一个位值乘以基数计算出来。所以上面5个位值是:
100= 1 = 1
101= 1×10 = 10
102= 10×10 = 100
103= 100×10 = 1000
104= 1000×10 = 10000
根据位值来读一个数,比如57 258,指的是有5个10 000,7个1 000,2个100,5个10,以及8个1。
就是说: 5×10 000 = 50 000 7×1 000 = 7 000 2×100 = 200 5×10 = 50 8×1 = 8 将这些结果相加,结果:50 000 + 7000 + 200 + 50 + 8=57 258。
我们对十进制非常熟悉。所以,我们很少会去考虑将一个数分解成位值。但是,这种方法对于阐明其他进制的数是非常至关重要的。
二进制数 计算机从最底层来看,只不过是电子开关的集合而已。而数字和字符是由这些开关的状态来表示的。由于一个开关仅有两种状态——“开”或者“关”,所以它使用二进制(Binary),或者说基数为2的计数系统(词根bi表示2)。一个基数为2的系统仅仅有两个数位:0和1。计算机通常将这两个数位集合成8个位值,即一个字节(Byte)或八位组字节(Octet)。
这8个位值是: 2726252423222120 位值这样计算:
20 = 1
21 = 1×2 = 2
22 = 2×2 = 4
23 = 4×2 = 8
24 = 8×2 = 16
25 = 16×2 = 32
26 = 32×2 = 64
27 = 64×2 = 128 所以一个二进制八位组的位值: 128 、64 、32 、16 、8 、4 、2 、1
因此,二进制八位组10010111可以这样理解:
1×128 = 128
0×64 = 0
0×32 = 0 1×16 = 16
0×8 = 0
1×4 = 4
1×2 = 2
1×1 = 1
或者:128 + 16 + 4 + 2 + 1 = 151 对于二进制数,因为每一个位值要么就是该值本身,要么就没有,所以比较简单。
另外一个例子:11101001 = 128 + 64 + 32 + 8 + 1 = 233。就是说,将二进制转换为十进制仅仅是一个将位值相加的过程,将十进制转换为二进制仅仅是将位值相减的过程。
例如,要将十进制数178转为二进制,首先把178减去最高的位值:
1、178大于128,所以我们就知道在该位值上有一个1: 178 – 128 = 50。
2、50比64小,该位值上有一个0。
3、50比32大,所以该位值上有一个1: 50 – 32 = 18。
4、18比16大,该位值上有一个1: 18 – 16 = 2。
5、2比8小,该位值上有一个0。
6、2比4小,该位值上有一个0。
7、2等于2,该位值上有一个1: 2 – 2 = 0。
8、0小于1,该位值上有一个0。
把这些步骤的结果综合起来,用二进制表示178是:10110010。
另外一个例子可能会有帮助。给出110:
1、110比128小,所以在该位值上有一个0。
2、110比64大,所以在该位值上有一个1: 110 – 64 = 46。
3、46比32大,所以在该位值上有一个1: 46 – 32 = 14。
4、14比16小,所以在该位值上有一个0。
5、14比8大,所以在该位值上有一个1: 14 – 8 = 6。
6、6比4大,所以在该位值上有一个1: 6 – 4 = 2。
7、第2个位值上有一个1: 2 – 2 = 0。
8、0比1小,所以在该位值上有一个0。 所以,110用二进制表示就是:01101110。
十六进制数 写一个二进制八位组并不有趣。对于经常要使用这些数字的人来说,受欢迎的是更简洁的表示法。一个可能的表示法是为每一个可能的八位组分配一个单独的字符。但是,8位有28 = 256种不同的组合,所以,用单独的字符表示所有八位组需要256个数位,或者说一个基数为256的计数系统。 将一个八位组看作是两个各4位的组合或许会更简单一些。例如,11010011可以看作是1101和0011。对4个位来说,有24 = 16种不同的组合,所以有基数16,或者说十六进制(Hexadecimal)计数系统,一个八位组可以用两位来表示(词根hex的意思是“six”,deci的意思是“ten”)。
十六进制 十进制 二进制
0 0 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5 5 0101
6 6 0110
7 7 0111
8 8 1000
9 9 1001
A 10 1010
B 11 1011
C 12 1100
D 13 1101
E 14 1110
F 15 1111
因为十六进制和十进制的前10个数字是一样的,所以我们有意在一个十六进制数前面加0x,或者在后面加一个h,以便和十进制数区分开。例如,十六进制数9应该写成0x9或者9h。 刚才学过二进制的表示法,很容易写出一个4位二进制数的十进制表达形式。同样也很容易将一个十进制数转为十六进制。
于是,我们可以很容易地通过3个步骤将一个二进制八位组转为十六进制:
1、将八位组分成2个4位的二进制数。
2、将每个4位二进制数转为十进制。
3、把每个十进制数用十六进制来表示。
例如:把11010011转为十六进制:
1、11010011变成1101和0011。
2、1101 = 8 + 4 + 1 = 13,0011 = 2 + 1 = 3。
3、13 = 0xD,3 = 0x3。 所以,11010011用十六进制表示就是0xD3。
把十六进制转为二进制是上述3步的简单逆序。例如,把0x7B转为二进制:
1、0x7 = 7,0xB = 11。
2、7 = 0111,11 = 1011。
3、把2个4位二进制数写在一起就是0x7B = 01111011,十进制为123。