载自:http://home.educities.edu.tw/wanker742126/asm/ap01.html
附录一 数字系统
进位法
自人类开始计算数字以来,发明了许多记录数字的方法,最直接的方法就是一条线代表一,两条线现代表二……,但是总不能以十个线条表示十,以一百个线条表示一百 ( 事实上,有些地区的人,一开始只能计算到三,三以上就被认为很多,人类计数,也是一部经历数万年的历史 )。有许多民族想出了解决之道,罗马人是其中之一,他们用一个符号代表五,另一个符号代表十,
I 表示一 X 表示十 M 表示一千
II 表示二 L 表示五十 V 表示五千
III 表示三 C 表示一百
V 表示五 D 表示五百
现在有些时钟钟面上,仍用罗马数字表示。这种方式虽然是很大的进步,但要表示百、千、万就麻烦了。( 注二:罗马数字)
我们现在用的数字系统是印度人发明的(有一说是阿拉伯人)和一般表示数字的方法有两点不同,一是零的发明,一是用位置表示位数。它用 1 代表一、2 代表二,一直到了九变成十的时候就发生进位,这时用 1 表示十位数,后面用 0 表示个位数,表示空位或没有的意思,于是就变成了 10 表示十。因此数字所在的位置不同,代表的意义就不同,小学生都知道 100 这个数有两个 0,但这两个零是不一样的。零的发明,在计数上有很重要的意义。
二进位和十进位
或许你会问,为什麽到十才发生进位,不在其他数字发生进位呢?人类採用十进位计数,并没有什麽特殊的理由,这完全是因为人类有十个手指头,你知道吗?有些地方因为连脚指头也用来计数,所以是二十进位。如果有外星人有 8 个手指头,说不定他们就是用八进位。而电脑只有两个「手指头」,记忆体中的电压如果是高电压代表一,低电压代表零,或者我们说高电压代表一、低电压代表零,所以电脑用「二进位」。如果有两个记忆体,就有四种表示方法,分别代表 0、1、2、3:
00 表示 0
01 表示 1
10 表示 2
11 表示 3
如果有三个记忆体,就有八种表示方法,代表 0 到 7:
000 表示 0
001 表示 1
010 表示 2
011 表示 3
100 表示 4
101 表示 5
110 表示 6
111 表示 7
你可以看得出来,如果每加入一个记忆体,可以计数的个数就变成原来的两倍。在电脑中用八个记忆体(也就是八位元)表示 0 到 255 共有 256 个数字。
0000 0000 表示 0
0000 0001 表示 1
0000 0010 表示 2
0000 0011 表示 3
0000 0100 表示 4
……
1111 1111 表示 255
事实上,上面这些例子的左边一大堆的 0 和 1 就是所谓的二进位数,也就是电脑看得懂的数,右边就是我们所熟知的十进位数。那二进位和十进位之间要怎麽转换呢?
二进位数变成十进位数,只要记得 2 的幂方就可以了。也就是说 20=1、21=2、22=4、23=8 ……,计算方式如下,最右边的那一位数若为一,表示加一,若为零表示不加;右边第二位数若为一表示加 2,若为零表示不加;右边第三位数若为一表示加 4,若零表示不加,依此类推,最后再总加起来就可以了。举例来说,下图
二进位 1010 1011 相当于十进位的 171(128+32+8+2+1=171)。
而十进位变成二进位就用连续减去 2 的幂方数即可。举例来说,把 171 变成二进位数方法如下:
171 - 128 = 43 128 的那一位数有一
43 - 64 不够减了,所以 64 那一位为零
43 - 32 = 11 32 的那一位数为一
11 - 16 不够减了,所以 16 那一位为零
11 - 8 = 3 8 的那一位数为一
3 - 4 不够减了,所以 4 那一位为零
3 - 2 = 1 2 的那一位数为一
1 最后还剩下一,所以最右边那一位数为一
最后综合上式,由上而下得到 1010 1011,就是 171 的二进位数。
十六进位和十进位
在组合语言中,如果用二进位表示数字,那就有一大串的 0 和 1,只要有一点点疏忽,就很容易出错,所以又有十六进位代替二进位较为方便。十六进位的一到九就是阿拉伯数字的 1 到 9,但是十以英文字的 A 表示,十一用 B 表示,…十五用 F 表示,就像下面的表一样:
表一:十六进位与二进位 | |||||
十进位 | 二进位 | 十六进位 | 十进位 | 二进位 | 十六进位 |
0 | 0000 | 0 | 8 | 1000 | 8 |
1 | 0011 | 1 | 9 | 1001 | 9 |
2 | 0000 | 2 | 10 | 1010 | A |
3 | 0000 | 3 | 11 | 1011 | B |
4 | 0100 | 4 | 12 | 1100 | C |
5 | 0101 | 5 | 13 | 1101 | D |
6 | 0110 | 6 | 14 | 1110 | E |
7 | 0111 | 7 | 15 | 1111 | F |
超过十六进位的 F 时,就发生进位了,这时就变成 10H,也就是 16D;11H 就是 17D。
在组合语言中为了区分这些数字系统,在数字后加上 H 表示十六进位数,加上 D 表示十进位数,加上 O 表示八进位数,加上 B 表示二进位数。此外如果是十六进位而且第一位是英文字母,要在最前面加上阿拉伯数字的 0,才不会使编译器误认为是变数名称,例如表示十六进位的 A12,要用 0A12h,英文字母用大写或小写都是一样的。
再仔细看看,一位的十六进位数刚好可以用四位元表示,也就是说,一位十六进位数必需用四位二进位数表示,换句话说二进位和十六进位之间的转换就是用这个关係,稍候再说明。
十六进位和十进位数之间的转换是最常用的,先说说如何将十六进位变成十进位。在说明如何变换前,先回想小学时假如有一个十进位数 1399,它的数值大小是不是等于 1x103+3x102+9x101+9 呢?这是因为是十进位,所以乘以 10 的幂方数﹔同理如果是十六进位就乘以 16 的幂方数,另外要注意,A 要等于 10d、B 等于 11d 等等。举例来说,现在想把 2AC1 这个十六进位数变成十进位数,
超过十六进位的 F 时,就发生进位了,这时就变成 10H,也就是 16D;11H 就是 17D。
在组合语言中为了区分这些数字系统,在数字后加上 H 表示十六进位数,加上 D 表示十进位数,加上 O 表示八进位数,加上 B 表示二进位数。此外如果是十六进位而且第一位是英文字母,要在最前面加上阿拉伯数字的 0,才不会使编译器误认为是变数名称,例如表示十六进位的 A12,要用 0A12h,英文字母用大写或小写都是一样的。
再仔细看看,一位的十六进位数刚好可以用四位元表示,也就是说,一位十六进位数必需用四位二进位数表示,换句话说二进位和十六进位之间的转换就是用这个关係,稍候再说明。
十六进位和十进位数之间的转换是最常用的,先说说如何将十六进位变成十进位。在说明如何变换前,先回想小学时假如有一个十进位数 1399,它的数值大小是不是等于 1x103+3x102+9x101+9 呢?这是因为是十进位,所以乘以 10 的幂方数﹔同理如果是十六进位就乘以 16 的幂方数,另外要注意,A 要等于 10d、B 等于 11d 等等。举例来说,现在想把 2AC1 这个十六进位数变成十进位数,
2AC1H = 2x163+10x162+12x161+1
= 2x4096+10x256+12x16+1
= 8192+2560+192+1
= 10945
十进位变十六进位可以用连续减法,或者用除法(事实上除法就是连续减法的结果),在此我用除法说明好了,连续减法可以参考上面十进位变二进位的方法。例如现在我把 10945D 变成十六进位,于是先除以 16(为什麽除以 16?想想看)得到馀数就是十六进位的个位数,其商再除 16 ……。例如将 11523 换成十六进位数,步骤如下:
11523 ÷16 =720 ..... 3 → 馀数为十六进位的个位数
720 ÷16 = 45 ..... 0 → 馀数为十六进位的十位数
45 ÷16 = 2 ..... 13 → 馀数 13 (即十六进位 0DH)为十六进位的百位数
2 ÷16 = 0 ..... 2 → 馀数为十六进位的千位数
所以 11523d=2D03h 。
十六进位和二进位
好了,现在如果你已经会二进位数,并且瞭解前面所提过的十六进位和二进位换算表(即表一)就很容易了。举例来说,有一个二进位数 110101101101000101 要变成十六进位,就将他由最低位数开始每四个位元一组变成 0011 0101 1011 0100 0101,然后
0011 变成 3
0101 变成 5
1011 变成 B
0100 变成 4
0101 变成 5
得到 35B45H。同理如果是十六进位变成二进位就将上述步骤反方向运算即可。
注一: 记得小学老师说:「十进位数 256 也可以看成 2x102+5x101+6x100 。」吗?这裡也是如此,连十六进位变成十进位、二进位变十进位也是用同样的原理。
注二:罗马数字用加法和减法的概念来简化计数方式。不过在说明如何用罗马数字表示之前,得先介绍罗马数字常见的符号:
I 表示一
V 表示五
X 表示十
L 表示五十
C 表示一百
D 表示五百
M 表示一千
表示五千
表示一万
在书写罗马数字时,必须由左边向右边书写,所以二用『II』表示,代表 1+1,三用『III』表示,代表 1+1+1,这两个数字,用的是加法的观念。但是四却用『IV』表示,代表 5-1 ,在罗马数字中为了简化书写,如果一个较小数写在较大数左边,则表示相减;反过来说,相同的数写在一起或小数写在大数右边,则表示相加。像前面所说的『II』和『III』,还有六也是用『VI』,它们都表示加法的概念。
我想把 1 到 100 的罗马数字表示方法列成一张表,就很清楚了。
阿拉伯数字 | 罗马数字 | 阿拉伯数字 | 罗马数字 | 阿拉伯数字 | 罗马数字 | 阿拉伯数字 | 罗马数字 |
1 | I | 26 | XXVI | 51 | LI | 76 | LXXVI |
2 | II | 27 | XXVII | 52 | LII | 77 | LXXVII |
3 | III | 28 | XXVIII | 53 | LIII | 78 | LXXVIII |
4 | IV | 29 | XXIX | 54 | LIV | 79 | LXXIX |
5 | V | 30 | XXX | 55 | LV | 80 | LXXX |
6 | VI | 31 | XXXI | 56 | LVI | 81 | LXXXI |
7 | VII | 32 | XXXII | 57 | LVII | 82 | LXXXII |
8 | VIII | 33 | XXXIII | 58 | LVIII | 83 | LXXXIII |
9 | IX | 34 | XXXIV | 59 | LIX | 84 | LXXXIV |
10 | X | 35 | XXXV | 60 | LX | 85 | LXXXV |
11 | XI | 36 | XXXVI | 61 | LXI | 86 | LXXXVI |
12 | XII | 37 | XXXVII | 62 | LXII | 87 | LXXXVII |
13 | XIII | 38 | XXXVIII | 63 | LXIII | 88 | LXXXVIII |
14 | XIV | 39 | XXXIX | 64 | LXIV | 89 | LXXXIX |
15 | XV | 40 | XL | 65 | LXV | 90 | XC |
16 | XVI | 41 | XLI | 66 | LXVI | 91 | XCI |
17 | XVII | 42 | XLII | 67 | LVII | 92 | XCII |
18 | XVIII | 43 | XLIII | 68 | LXVIII | 93 | XCIII |
19 | XIX | 44 | XLIV | 69 | LXIX | 94 | XCIV |
20 | XX | 45 | XLV | 70 | LXX | 95 | XCV |
21 | XXI | 46 | XLVI | 71 | LXXI | 96 | XCVI |
22 | 47 | XLVII | 72 | LXXII | 97 | XCVII | |
23 | XXIII | 48 | XLVIII | 73 | LXXIII | 98 | XCVIII |
24 | XXIV | 49 | XLIX | 74 | LXXIV | 99 | XCIX |
25 | XXV | 50 | L | 75 | LXXV | 100 | C |
其中有两处是比较特别的,一是『49』,另一处是『99』,它们不是分别用『IL』和『IC』表示。49 应该先写代表『40』的『XL』,再写代表『9』的『IX』,所以『49』应该用『XLIX』表示。同理『99』应该用『XCIX』表示。