请问十进制转八进制的10000,用二进制、八进制、十六进制分别怎么表示?

二进制,十六进制,八进制的换算
  0,16,2进制的互相转换  所谓16进制,就是由0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F共16个数字组成。逢16进一位,下面就讲讲在没有任何工具的情  况下如何将一10进制转化为16进制:  1000除以16得62余8,那么最低位为8,再将62除以16得3余14,那么倒数第2为E(14对于16进制来说是E),3比16小了,所以不用继续除了  ,总的就是3E8,为1000的16进制数。  想要将16进制的数转化为10进制,只需将上面的步骤反过来做就可以了。不用我多说吧!  2进制仅由0、1两个数字组成,逢1进一。要将一10进制化为2进制,介绍一个简单的方法,先将10进制的数化为16进制,再化为2进制,举  个例子:  515对应16进制为203H,将203转为2进制则为0010(2) 0000(0) 0011(3),一个位数对2进制来说是4个字符。0H就是0000、1H就是  0001、……、0EH就是1110、OFH为1111,大家可自己推一下。  总之大家一定要熟练掌握各个进制的互相转化,尤其是100以内10--16和16--10的互相转化要记住。  16-10H、32-20H、48-30H、64-40H、80-50H、96-60H、100-64H,255-FFH,65535-FF FFH,1677万-FF FF FFH,前为10进制,后有H的为16  进制,这些能记住最好,以后修改就方便许多了。  二进制  二进制是逢2进位的进位制,0、1是基本算符。  现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。  二进制四则运算规则  加法  0+0=0,0+1=1+0=1,1+1=10  减法  0-0=0,1-0=1,1-1=0,0-1=-1  乘法  0×0=0,0×1=1×0=0,1×1=1  除法  0÷1=0,1÷1=1  一、什么是二进制  在现实生活和记数器中,如果表示数的“器件”只有两种状态,如电灯的“亮”与“灭”,开关的“开”与“关”。一种状态表示数码0,另一种状态表示数码1,1加1应该等于2,因为没有数码2,只能向上一个数位进一,就是采用“满二进一”的原则,这和十进制是采用“满十进一”原则完全相同。  1+1=10,10+1=11,11+1=100,100+1=101,  101+1=110,110+1=111,111+1+=1000,……,  可见二进制的10表示二,100表示四,1000表示八,10000表示十六,……。  二进制同样是“位值制”。同一个数码1,在不同数位上表示的数值是不同的。如11111,从右往左数,第一位的1就是一,第二位的1表示二,第三位的1表示四,第四位的1表示八,第五位的1表示十六。用大家熟悉的十进制说明这个二进制数的含意,有以下关系式  (11111)(二进制)=1×24+1×23+1×22+1×2+1(十进制)  一个二进制整数,从右边第一位起,各位的计数单位分别是1,2,22,23,…,2n,…。  1为什么需要八进制和十六进制?  编程中,我们常用的还是10进制……必竟C/C++是高级语言。  比如:  int a = 100,b = 99;  不过,由于数据在计算机中的表示,最终以二进制的形式存在,所以有时候使用二进制,可以更直观地解决问题。  但,二进制数太长了。比如int 类型占用4个字节,32位。比如100,用int类型的二进制数表达将是:  00 00  面对这么长的数进行思考或操作,没有人会喜欢。因此,C,C++ 没有提供在代码直接写二进制数的方法。  用16进制或8进制可以解决这个问题。因为,进制越大,数的表达长度也就越短。不过,为什么偏偏是16或8进制,而不其它的,诸如9或20进制呢?  2、8、16,分别是2的1次方,3次方,4次方。这一点使得三种进制之间可以非常直接地互相转换。8进制或16进制缩短了二进制数,但保持了二进制数的表达特点。在下面的关于进制转换的课程中,你可以发现这一点。  6.2 二、八、十六进制数转换到十进制数  6.2.1 二进制数转换为十进制数  二进制数第0位的权值是2的0次方,第1位的权值是2的1次方……  所以,设有一个二进制数:,转换为10进制为:  下面是竖式:   换算成 十进制  第0位 0 * 20& =& 0  第1位 0 * 21& =& 0  第2位 1 * 22& =& 4  第3位 0 * 23& =& 0  第4位 0 * 24& =& 0  第5位 1 * 25& = 32  第6位 1 * 26& = 64  第7位 0 * 27& =& 0&&&& +  ---------------------------  100  用横式计算为:  0 * 20 + 0 * 21 + 1 * 22 + 1 * 23 + 0 * 24 + 1 * 25 + 1 * 26 + 0 * 27 = 100  0乘以多少都是0,所以我们也可以直接跳过值为0的位:  1 * 22 + 1 * 23 +& 1 * 25 + 1 * 26 = 100
  6.2.2 八进制数转换为十进制数  八进制就是逢8进1。  八进制数采用 0~7这八数来表达一个数。  八进制数第0位的权值为8的0次方,第1位权值为8的1次方,第2位权值为8的2次方……  所以,设有一个八进制数:1507,转换为十进制为:  用竖式表示:  1507换算成十进制。  第0位 7 * 80 = 7  第1位 0 * 81 = 0  第2位 5 * 82 = 320  第3位 1 * 83 = 512&& +  --------------------------  839  同样,我们也可以用横式直接计算:  7 * 80 + 0 * 81 + 5 * 82 + 1 * 83 = 839  结果是,八进制数 1507 转换成十进制数为 839  6.2.3 八进制数的表达方法  C,C++语言中,如何表达一个八进制数呢?如果这个数是 876,我们可以断定它不是八进制数,因为八进制数中不可能出7以上的阿拉伯数字。但如果这个数是123、是567,或,那么它是八进制数还是10进制数,都有可能。  所以,C,C++规定,一个数如果要指明它采用八进制,必须在它前面加上一个0,如:123是十进制,但0123则表示采用八进制。这就是八进制数在C、C++中的表达方法。  由于C和C++都没有提供二进制数的表达方法,所以,这里所学的八进制是我们学习的,CtC++语言的数值表达的第二种进制法。  现在,对于同样一个数,比如是100,我们在代码中可以用平常的10进制表达,例如在变量初始化时:  int a = 100;  我们也可以这样写:  int a = 0144; //0144是八进制的100;一个10进制数如何转成8进制,我们后面会学到。  千万记住,用八进制表达时,你不能少了最前的那个0。否则计算机会通通当成10进制。不过,有一个地方使用八进制数时,却不能使用加0,那就是我们前面学的用于表达字符的“转义符”表达法。  6.2.4 八进制数在转义符中的使用  我们学过用一个转义符'\'加上一个特殊字母来表示某个字符的方法,如:'\n'表示换行(line),而'\t'表示Tab字符,'\''则表示单引号。今天我们又学习了一种使用转义符的方法:转义符'\'后面接一个八进制数,用于表示ASCII码等于该值的字符。  比如,查一下第5章中的ASCII码表,我们找到问号字符(?)的ASCII值是63,那么我们可以把它转换为八进值:77,然后用 '\77'来表示'?'。由于是八进制,所以本应写成 '\077',但因为C,C++规定不允许使用斜杠加10进制数来表示字符,所以这里的0可以不写。  事实上我们很少在实际编程中非要用转义符加八进制数来表示一个字符,所以,6.2.4小节的内容,大家仅仅了解就行。  6.2.5 十六进制数转换成十进制数  2进制,用两个阿拉伯数字:0、1;  8进制,用八个阿拉伯数字:0、1、2、3、4、5、6、7;  10进制,用十个阿拉伯数字:0到9;  16进制,用十六个阿拉伯数字……等等,阿拉伯人或说是印度人,只发明了10个数字啊?  16进制就是逢16进1,但我们只有0~9这十个数字,所以我们用A,B,C,D,E,F这五个字母来分别表示10,11,12,13,14,15。字母不区分大小写。  十六进制数的第0位的权值为16的0次方,第1位的权值为16的1次方,第2位的权值为16的2次方……  所以,在第N(N从0开始)位上,如果是是数 X (X 大于等于0,并且X小于等于 15,即:F)表示的大小为 X * 16的N次方。  假设有一个十六进数 2AF5, 那么如何换算成10进制呢?  用竖式计算:  2AF5换算成10进制:  第0位:& 5 * 160 = 5  第1位:& F * 161 = 240  第2位:& A * 162 = 2560  第3位:& 2 * 163 = 8192& +  -------------------------------------  10997  直接计算就是:  5 * 160& + F * 161 + A * 162 + 2 * 163 = 10997  (别忘了,在上面的计算中,A表示10,而F表示15)  现在可以看出,所有进制换算成10进制,关键在于各自的权值不同。  假设有人问你,十进数 1234 为什么是 一千二百三十四?你尽可以给他这么一个算式:  1234 = 1 * 103 + 2 * 102 + 3 * 101 + 4 * 100  6.2.6& 十六进制数的表达方法  如果不使用特殊的书写形式,16进制数也会和10进制相混。随便一个数:9876,就看不出它是16进制或10进制。  C,C++规定,16进制数必须以 0x开头。比如 0x1表示一个16进制数。而1则表示一个十进制。另外如:0xff,0xFF,0X102A,等等。其中的x也也不区分大小写。(注意:0x中的0是数字0,而不是字母O)  以下是一些用法示例:  int a = 0x100F;  int b = 0x70 +  至此,我们学完了所有进制:10进制,8进制,16进制数的表达方式。最后一点很重要,C/C++中,10进制数有正负之分,比如12表示正12,而-12表示负12,;但8进制和16进制只能用达无符号的正整数,如果你在代码中里:-078,或者写:-0xF2,C,C++并不把它当成一个负数。  6.2.7 十六进制数在转义符中的使用  转义符也可以接一个16进制数来表示一个字符。如在6.2.4小节中说的 '?' 字符,可以有以下表达方式:  '?'&&&& //直接输入字符  '\77'&& //用八进制,此时可以省略开头的0  '\0x3F' //用十六进制  同样,这一小节只用于了解。除了空字符用八进制数 '\0' 表示以外,我们很少用后两种方法表示一个字符。  6.3 十进制数转换到二、八、十六进制  6.3.1 10进制数转换为2进制数  给你一个十进制,比如:6,如果将它转换成二进制数呢?  10进制数转换成二进制数,这是一个连续除2的过程:  把要转换的数,除以2,得到商和余数,  将商继续除以2,直到商为0。最后将所有余数倒序排列,得到数就是转换结果。  听起来有些糊涂?我们结合例子来说明。比如要转换6为二进制数。  “把要转换的数,除以2,得到商和余数”。  那么:  要转换的数是6, 6 ÷ 2,得到商是3,余数是0。 (不要告诉我你不会计算6÷3!)  “将商继续除以2,直到商为0……”  现在商是3,还不是0,所以继续除以2。  那就: 3 ÷ 2, 得到商是1,余数是1。  “将商继续除以2,直到商为0……”  现在商是1,还不是0,所以继续除以2。  那就: 1 ÷ 2, 得到商是0,余数是1 (拿笔纸算一下,1÷2是不是商0余1!)  “将商继续除以2,直到商为0……最后将所有余数倒序排列”  好极!现在商已经是0。  我们三次计算依次得到余数分别是:0、1、1,将所有余数倒序排列,那就是:110了!  6转换成二进制,结果是110。  把上面的一段改成用表格来表示,则为:  被除数 计算过程 商 余数  6 6/2 3 0  3 3/2 1 1  1 1/2 0 1  (在计算机中,÷用 / 来表示)  如果是在考试时,我们要画这样表还是有点费时间,所更常见的换算过程是使用下图的连除:  请大家对照图,表,及文字说明,并且自已拿笔计算一遍如何将6转换为二进制数。  说了半天,我们的转换结果对吗?二进制数110是6吗?你已经学会如何将二进制数转换成10进制数了,所以请现在就计算一下110换成10进制是否就是6。  6.3.2 10进制数转换为8、16进制数  非常开心,10进制数转换成8进制的方法,和转换为2进制的方法类似,惟一变化:除数由2变成8。  来看一个例子,如何将十进制数120转换成八进制数。  用表格表示:  被除数 计算过程 商 余数  120 120/8 15 0  15 15/8 1 7  1 1/8 0 1  120转换为8进制,结果为:170。  非常非常开心,10进制数转换成16进制的方法,和转换为2进制的方法类似,惟一变化:除数由2变成16。  同样是120,转换成16进制则为:  被除数 计算过程 商 余数  120 120/16 7 8  7 7/16 0 7  120转换为16进制,结果为:78。  请拿笔纸,采用(图:1)的形式,演算上面两个表的过程。
  6.4 二、十六进制数互相转换  二进制和十六进制的互相转换比较重要。不过这二者的转换却不用计算,每个C,C++程序员都能做到看见二进制数,直接就能转换为十六进制数,反之亦然。  我们也一样,只要学完这一小节,就能做到。  首先我们来看一个二进制数:1111,它是多少呢?  你可能还要这样计算:1 * 20 + 1 * 21 + 1 * 22 + 1 * 23 = 1 * 1 + 1 * 2 + 1 * 4 + 1 * 8 = 15。  然而,由于1111才4位,所以我们必须直接记住它每一位的权值,并且是从高位往低位记,:8、4、2、1。即,最高位的权值为23 = 8,然后依次是 22 = 4,21=2, 20 = 1。  记住8421,对于任意一个4位的二进制数,我们都可以很快算出它对应的10进制值。  下面列出四位二进制数 xxxx 所有可能的值(中间略过部分)  仅4位的2进制数& 快速计算方法&& 十进制值&&&& 十六进值  1111&&&&&&& = 8 + 4 + 2 + 1& = 15&&&&&&&&& F  1110&&&&&&& = 8 + 4 + 2 + 0& = 14&&&&&&&&& E  1101&&&&&&& = 8 + 4 + 0 + 1& = 13&&&&&&&&& D  1100&&&&&&& = 8 + 4 + 0 + 0& = 12&&&&&&&&& C  1011&&&&&&& = 8 + 4 + 0 + 1& = 11&&&&&&&&& B  1010&&&&&&& = 8 + 0 + 2 + 0& = 10&&&&&&&&& A  1001&&&&&&& = 8 + 0 + 0 + 1& = 10&&&&&&&&& 9  ....  0001&&&&&&& = 0 + 0 + 0 + 1& = 1&&&&&&&&&& 1  0000&&&&&&& = 0 + 0 + 0 + 0& = 0&&&&&&&&&& 0  二进制数要转换为十六进制,就是以4位一段,分别转换为十六进制。  如(上行为二制数,下面为对应的十六进制):   ,
,   F&&& D&& ,& A&&& 5&& ,& 9&&& B  反过来,当我们看到 FD时,如何迅速将它转换为二进制数呢?  先转换F:  看到F,我们需知道它是15(可能你还不熟悉A~F这五个数),然后15如何用8421凑呢?应该是8 + 4 + 2 + 1,所以四位全为1 :1111。  接着转换 D:  看到D,知道它是13,13如何用8421凑呢?应该是:8 + 2 + 1,即:1011。  所以,FD转换为二进制数,为:   由于十六进制转换成二进制相当直接,所以,我们需要将一个十进制数转换成2进制数时,也可以先转换成16进制,然后再转换成2进制。  比如,十进制数 1234转换成二制数,如果要一直除以2,直接得到2进制数,需要计算较多次数。所以我们可以先除以16,得到16进制数:  被除数 计算过程 商 余数   77 2  77 77/16 4 13 (D)  4 4/16 0 4  结果16进制为: 0x4D2  然后我们可直接写出0x4D2的二进制形式: 10。  其中对映关系为:  0100 -- 4  1011 -- D  0010 -- 2  同样,如果一个二进制数很长,我们需要将它转换成10进制数时,除了前面学过的方法是,我们还可以先将这个二进制转换成16进制,然后再转换为10进制。  下面举例一个int类型的二进制数:  11   我们按四位一组转换为16进制: 6D E5 AF 1B  二进制只有0和1两个数字,逢2进一;  十进制则逢十进一,依次类推~~~~  二进制与十进制之间的转换关系,举个例子:十进制数4,化为二进制则为100。(0*2^1+0*2^1+1*2^2)  再举个例子:十进制数11,化为二进制为1011。  (1*2^0+1*2^1+0*2^2+1*2^3)  找到规律了吗?  十六进制、八进制就是8的几次方~~~~类推下去
全国计算机等级考试真题及解析
(&15059人&已观看&)
(&20365人&已观看&)
(&13521人&已观看&)
本文关键词:     
已有(0)条评论
3秒钟快速注册
文明上网,登录发帖
精选内容新闻排行校园热点
各地课程推荐深圳广州上海北京南京杭州苏州天津常年开课¥750&&&&罗湖区常年开课¥750&&&&罗湖区常年开课¥750&&&&罗湖区常年开课¥750&&&&罗湖区更多&&&常年开课¥1380&&&&天河区常年开课¥980&&&&白云区常年开课¥980&&&&天河区常年开课¥1380&&&&天河区更多&&&常年开课¥1280&&&&黄浦区常年开课¥680&&&&徐汇区常年开课¥680&&&&徐汇区常年开课¥1280&&&&更多&&&常年开课¥1500&&&&海淀区常年开课¥1500&&&&海淀区常年开课¥1500&&&&海淀区常年开课¥1500&&&&海淀区更多&&&常年开课详询&&&&玄武区常年开课¥450&&&&下关区常年开课¥450&&&&栖霞区常年开课¥450&&&&下关区更多&&&常年开课¥700&&&&江干区常年开课¥600&&&&江干区常年开课¥700&&&&江干区常年开课¥850&&&&江干区更多&&&常年开课¥450&&&&工业园区常年开课¥450&&&&工业园区常年开课¥450&&&&工业园区常年开课¥450&&&&工业园区更多&&&常年开课¥950&&&&河西区常年开课¥950&&&&河西区常年开课¥950&&&&河西区常年开课¥1000&&&&更多&&&
8-148-148-148-148-148-14
8-148-148-148-148-148-14您所在的位置: &
不同进制的表示方法
不同进制的表示方法
刘志军/陈涛
清华大学出版社
《计算机基础实用教程(第2版)》第1章计算机基础概论,通过本章的学习,读者应了解计算机的概念及其发展史、计算机的组成以及计算机中的数制与编码等知识。本节为大家介绍不同进制的表示方法。
1.3.2& 不同进制的表示方法
计算机必须采用某一种方式来存储或表示数据,这种方式就是计算机中的数制。数制,即进位计数制,是人们利用数字符号按进位原则进行数据大小计算的方法。通常是以十进制来进行计算的。另外,还有二进制、八进制和十六进制等。
在计算机的数制中,有数码、基数和位权这3个概念必须掌握。下面将简单地介绍这3个概念。
数码:一个数制中表示基本数值大小的不同数字符号。例如,十进制有10个数码:0、1、2、3、4、5、6、7、8、9。
基数:一个数值所使用数码的个数。例如,二进制的基数为2,十进制的基数为10。
位权:一个数值中某一位上的1所表示数值的大小。例如,十进制的123,1的位权是100,2的位权是10,3的位权是1。
1. 十进制(Decimal notation)
十进制的特点如下。
有10个数码:0、1、2、3、4、5、6、7、8、9。
基数:10。
逢十进一(加法运算),借一当十(减法运算)。
按权展开式。对于任意一个n位整数和m位小数的十进制数D,均可按权展开为:D=Dn-1?10n-1+Dn-2?10n-2+…+D1?101+D0?100+D-1?10-1+…+D- m?10-m
【例1-1】将十进制数314.16写成按权展开式形式。
314.16=3×102+1×101+4×100+1×10-1+6×10-2
2. 二进制(Binary notation)
二进制的特点如下。
有两个数码:0、1。
逢二进一(加法运算);借一当二(减法运算)。
按权展开式。对于任意一个n位整数和m位小数的二进制数D,均可按权展开为:
D=Bn-1?2n-1+Bn-2?2n-2+…+B1&?21+B0?20+B-1?2-1+…+B-m?2-m
【例1-2】把(写成展开式,它表示的十进制数为:
1×23+1×22+0×21+1×20+0×2-1+1×2-2=(13.25)10
3. 八进制(Octal notation)
八进制的特点如下。
有8个数码:0、1、2、3、4、5、6、7。
逢八进一(加法运算),借一当八(减法运算)。
按权展开式。对于任意一个n位整数和m位小数的八进制数D,均可按权展开为:D=On-1?8n-1+…+O1?81+O0?80+O-1?8-1+…+O-m?8-m
【例1-3】(317)8相当于十进制数为:3×82+1×81+7×80=(207)10
4. 十六进制(Hexadecimal notation)
十六进制的特点如下。
有16个数码:0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。
基数:16。
逢十六进一(加法运算),借一当十六(减法运算)。
按权展开式。对于任意一个n位整数和m位小数的十六进制数D,均可按权展开为:D=Hn-1?16n-1+…+H1?161+H0?160+H-1?16-1+…+H-m?16-m
【例1-4】十六进制数(3C4)16代表的十进制数为:3×162+12×161+4×160=(964)10
二进制数与其他进制数之间的对应关系如表1-1所示。
表1-1& 二进制数与其他进制数之间的对应关系
【责任编辑: TEL:(010)】&&&&&&
关于&&的更多文章
本书全面讲解WPF的实际工作原理,是一本WPF权威著作。在紧贴实用
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
本书通过对目前中国企业在风险管理和内部控制工作中的
解释ASP.NET MVC框架与"文件页"Web框架的不同之处
本书以Android 4.X进行开发示范,通过大量图示与step
本书是作者深入研究SQL Server 2005数据库体系结构和内部机制的经验总结。
全书不拘泥于具体的管理操作,而是通过对存储的数据
51CTO旗下网站后使用快捷导航没有帐号?
只需一步,快速开始
查看: 23861|回复: 1
二进制,八进制,十进制和十六进制:
UID801在线时间 小时积分2358帖子离线16390 天注册时间
银牌会员, 积分 2358, 距离下一级还需 642 积分
十进制数的特点是用十个数码(0~9)表示所有的数,基数是10,采用逢十进一的记数方法
二进制数的特点是用两个数码(0~1)表示所有的数,基数是2,采用逢二进一的记数方法
八进制数的特点是用八个数码(0~7)表示所有的数,基数是8,采用逢八进一的记数方法
十六进制数的特点是用十六个数码(0~f)表示所有的数,基数是16,采用逢十六进一的记数方法
————————————————————————————————————————
◆计算机中采用二、八、十、十六四种计数制
◆计算机只能识别二进制数,其它进制数计算机均不能识别
◆采用十进制数,是因为我们对它熟悉,采用八、十六进制数是因为它们可以缩短二进制数的表示位数
ASCII码表:
UID3685在线时间 小时积分1360帖子离线16390 天注册时间
银牌会员, 积分 1360, 距离下一级还需 1640 积分
在发出这篇文字之前,我必须说明的是,这一些“文字”本来是不成其为文字的。在我发现它们的时候,它们的存在形态是一堆布满灰尘的磁片。我怀着好奇心将它们在我的电脑中一一打开,当然,除了满屏幕的乱码以外一无所获。但我的热情并未因此削减,在一位精通编码的朋友的提示下,我使用了一种极为常用的解码系统。令人欣慰的是,密码变成了断断续续的文字,似乎是某一个人(或一群人)的日常琐事的记载,又象是一些观点的零散发布。我试图用较为通俗的文字来将这些记载整理出来,并且按照自己的感觉大致分成了几类。在进行这些事情的同时,我愈来愈发觉这些并不是简单的记录,而象是某种传说中的东西。就这样,我努力保持这些东西的原貌,整理成了下面的文字。只是一点,在原文中多次出现的ppxll,似乎是记载的中心,但却没有适当的译称,我便妄自将其尊称为“大师”。
其实这就是组合语言的艺术:
&&一、对程序的认识
& & 写作程序不难,但要写出好程序却不容易。这就好象画图一样,人人都能画,而画
出来的图却可能有天壤之别。
& & 想作一个好画家,首先要有观察及分析的能力,面对着杂乱的事物,先整理出头绪,
找到主题。再在画布上勾出轮廓,这叫做「布局」。布局完毕,根据实际的环境,决定
作图的先后「顺序」。顺序是一种层次观念,景物及色彩都有一定的层次,绝不可随意
所之,想到哪里,画到哪里。
& & 观察考虑完毕,即开始准备,先将画笔、调色板等工具放妥,把要表现的主要色彩
也调好。最后是选择适当的画笔,蘸上色彩,按照所观察的结果,涂在画布上。
& & 画图颇重风格,有些个人主义的艺术家,技巧并不精通,只因为时代潮流或历史条
件,创造了某种独特的风格,就得以成名享利。一般的画家则不然,不论是「工笔」抑
或「写意」画,全靠其技巧及素养,始能求生存。至于艺术大师,则首重风格,再加上
素养、技巧,方可扬名立万,永垂不朽。
& & 最糟糕的画匠,既没有观察能力,更谈不上技巧和风格,除了照着别人的作品抄袭、
模仿外,创造不出有价值的作品。若程序员也如此,只能照着别人的意思,填填指令,
不过是个程序匠罢了。
& & 在观察分析之下,把欲表现的内容整理成为具体的步骤,用计算机术语来说,是为
「程序分析」,相当于画画中的「布局」。再下去,便是「流程」制作,或是作画的顺
序。将各种程序的层次安排妥当,才能开始写作程序,相当于开始作画。
& & 这些观念牵涉甚广,不是三言两语可以说完。本书仅以汇编语言写作的训练为目的。
如果读者能善用汇编语言的各种技巧,又能充份认识所要完成的工作,至少可以满足
「工笔画」的条件。对一个电脑程序而言,目前画「工笔画」的价值要比「写意」为高。
& & 下面,我们要以工笔画的立场,来理解汇编语言的应用。对油画或水彩画而言,色
料相当于程序用的「数据」,调色盘就是运用数据的「暂存器」,画笔等于「指令」,
一切都准备妥当,所谓「作画」就是「写程序」。
& & 程序是由一系列的定义和指令组织成的可执行的程序,需由一种档案的形式(.ASM)
经过编译程序 (MASM.EXE) 的处理,将原始档转变为目的档(.OBJ),然后再将一个或数
个目的档经过联结(LINK.EXE)成为执行档(.EXE),或者再用 EXE2BIN. EXE 制成记忆
限在64KB以下的命令档(.COM)。
& & 程序员应熟悉上述过程中的每一细节,方能顺利完成程序写作。
& & 程序的写作方式本无定则,完全看需求及应用而定。可是正如一幅画,在布局时,
程序员应该先有全部的观念,然后逐步实行。为了提高效率,这些步骤,有必要加以归
类。结果就是所谓的模块。
& & 模块的良窳,决定了程序写作、修改及再应用的效能。在写作时要求理念一贯,连
续进行。修改应方便灵活,不致错误丛生。而应用上功能要完整,可以独立调用。
& & 根据上述条件,程序的结构大致上可分为:
&&1,主程序:连贯性的处理过程,应该一次考虑清楚,细节暂& & 时放在一边,先把大
架构写出来,以免顾首不顾尾。在空间足够的情形下,大架构应该是一个完整的模块,
且在整体的观念下,统一处理。
& && &&&这种做法,对程序侦错及修改有很大的帮助。因为修改和调整最多、对功能影
响最大的,必然是主程序。若主程序都在同一模块中,比较容易得到理想的效果。
&&2,子程序:子程序都是一些细节的处理,可以用'CALL'的方式执行。原则上说来,细
节的处理经常重复发生在不同& & 的情况下,作为子程序相当有利。只是应该注意调用
的手& & 续,为了效率,通常将需要处理的参数或数据,经由寄存器或者必要时用缓冲
& && &&&既然是数个程序均可共享的子程序,而且此类程序为一独立的过程,所以应该
事先分别测试,保证无误。
& && &&&此外,各子程序的入口处,宜明白的交待寄存器的使用方式,且要能一目了然。
&&3,子程序:子程序与子程序有一点不同,就是具备完整的机能。所谓完整的机能,指
该段程序可以独立执行、有固定的功能。在应用时,两者没有分别,然而在写作时,子
程序的考虑要慎重些。
&&4,数据档:数据档也可以视为一种静态的程序,虽然不是执行用的,但却是执行时不
可或缺的素材。数据档的设计应该注意空间的利用,等长度的数据结构最具效率,最好
保证数据起点为双数,以节省16位总线的执行速度。
& && &&&在应用缓冲器时,切忌随意设置,往往程序员们设了一缓冲器,等后来发现没
有必要,再想删掉就麻烦大了。所以事先应安排妥当,以便于随时查找和调整。安排的
方式视使用的情形而定,有的以模块归类;也可以用字母排序为依据;再不然就加上详
细注释说明功能及使用的程序标号。
&&5,应用表:在本书第四章第六节将介绍应用表的功能和应用方式,此类表一次设计完
成以后,很少需要再修改,为了工作效率,独立成为一个档案,自有其必要性。
& & 此外,各种程序的命名最好能有代表性,以便于应用;程序不能太大,否则编辑耗
时费事;分档时,则要注意标号宣告及各段安排的问题。在磁盘中,应该专辟一个子目
录,不要把各种不相干的程序,都混合在一起。
& & 第二章三、四节中已规定了格式的标准,此处仅再补充一点。即各缓冲器的定义与
使用时的长度应相等,否则在编译或联结时,容易发生错误。联结时,有时并无足够的
错误讯息,供程序员得知错误产生的原委。最难理解的错误,往往与缓冲器的定义有关,
即定义的类型与使用的类型不一致。另外一个情况是段值的改变,其补救方法为在应用
时,临时加一「前置定义」。
& & 所谓「前置定义」是指当寄存器为一字符时,其前应加写BYTE PTR,否则用 WORD
PTR 以确定其值,即可保证安全。
& & 如:MOV&&BYTE PTR BBSDOT1,AL
& & 此外,每当段值有所改变时,都加写一条:
& & ASSUME&&CS:XXX,DS:YYY,ES:ZZZ
& & 这种用法,完全是给汇编程序「看」的,程序本身并没有增加任何指令。
& & 其它规定,请参阅各相关手册。
& && && && && && && && && && & 二、对数据的认识
& & 在画布上,所有色彩都是由红、蓝、黄三原色及白色调制而成,了解色彩的变化是
画家的基本素养。在计算机中,所有的数据则都由二进制数据组成,要写程序,必须对
二进制的特性先有深刻的认识。
& & 绝大部份的程序员,都不知道二进制数据的妙用,充其量能够很快地换算二进制与
十进制的数值。再不然,由二进制值领会到图形的点阵排列,如此而已。
& & 二进制就是开关的观念,把一连串的开关联在一起,其所能发生的作用,完全在于
每一个开关、以及各开关组合应用的功能。
& & 说得明确一点,先要将各种需要设计的功能分析清楚,找出其共通的因素,如果这
些因素能用「开」及「关」两个简单的状态代表,则可以用二进制制加以控制。在理论
上,一开一关只有两种作用,而两组开关就有222 种作用,最理想的设计&&是将开关的
排列组合数用到极限。
& & 举例而言,计算机上应用的彩色,就是最理想的设计之一。在计算机中,最基本的
应用单位为「字符」(Byte),每一字符有8个「位」(Bit),相当于8个「开关」。为了
要最精简地应用多种彩色,只以三原色与辉度组合,八个开关就能产生 256种不同的彩
色。兹将各开关所代表的彩色分列如下:
& & 开关一 (bit 1):正蓝色
& & 开关二 (bit 2):正绿色
& & 开关三 (bit 3):正红色
& & 开关四 (bit 4):灰色 (高辉度)
& & 开关五 (bit 5):黑色 (低辉度)
& & 开关六 (bit 6):浅蓝色
& & 开关七 (bit 7):浅红色
& & 开关八 (bit 8):浅青色
& && &★上述 (bit n) 是从 n=1 开始计算。
& & 应该注意的一点,是计算机的基本单位在于八个开关,不用足就是浪费。如果8个
不够,再增加便有16个。所以,因事制宜,在设计的时候,唯有用8的倍数才划算。
& & 但是,宇宙中的事物,不见得刚好是八的倍数。如果设计的人没有这种认识,不能
把所处理的数据,以8为限制条件去划分,就无法利用这种有利的条件,当然,也就得
不到最理想的结果。
& & 所以,要想程序具有最高的效率,首先要把数据整理成为八的倍数值结构。把数据
整理为最有效的结构方式,称为「数据结构」,关于这一点,在后面将有较详细的例证。
& & 每个字符有 256种排列组合,即相当于 256个十进制的数字。为了方便人的理解,
通常将字符写成十六进制形式,并在其数字后加一'H',以别于十进制数字。
& & 兹将十进制与十六进制对应表列于下面:
& & 二进制值& & 八进位值& & 十进制值& & 十六进制值
& && &&&0& && && &&&0& && && &&&0& && && &&&0H
& && &&&1& && && &&&1& && && &&&1& && && &&&1H
& && &*10& && && &&&2& && && &&&2& && && &&&2H
& && & 11& && && &&&3& && && &&&3& && && &&&3H
& & *100& && && &&&4& && && &&&4& && && &&&4H
& && &101& && && &&&5& && && &&&5& && && &&&5H
& && &110& && && &&&6& && && &&&6& && && &&&6H
& && && && && &&&7& && && &&&7& && && &&&7H
& & *1000& && && &*10& && && &&&8& && && &&&8H
& & 1001& && && & 11& && && &&&9& && && &&&9H
& & 1010& && && & 12& && && &*10& && && & 0AH
& & 1011& && && & 13& && && & 11& && && & 0BH
& & 1100& && && & 14& && && & 12& && && & 0CH
& & 1101& && && & 15& && && & 13& && && & 0DH
& & 0& && && & 16& && && & 14& && && & 0EH
& & 1& && && & 17& && && & 15& && && & 0FH
& &*10000& && && &*20& && && & 16& && && &*10H
& && &★&&凡前有 *者表示进位。
& && &★★二进制数后应加'B',八进位后应加'O'。
& & 由上可知,十六进制仍沿用十进制数字,只是到了10时,已无现成数字可用,只好
借用英文字母。在程序中,汇编程序为了分辨ASCII 字符与十六进制数值,通常规定凡
十六进制数值以英文字母开始者,在其字母前加一'0'。
& && && && && && && && && && &三、对寄存器的认识
& & 暂存器 (Register) 相当于调色皿,数据相当于色料。把色料放进调色皿里,为的
是要得到预定的效果,寄存器对于数据亦然。
& & 调色皿有大有小,深度有深有浅,其目的是针对不同的情况,以作有效的处理。寄
存器也是一样,应用得好,程序会很精简,容易修改、阅读。否则,想到哪一个就用哪
一个,没有原则,没有章法,这种程序委实不敢恭维。
& & 寄存器的重要性,在于处理方便灵活、速度快,占用空间小。不幸8088 CPU的寄存
器很少,用起来总是捉襟见肘,辛苦异常。正因为此,寄存器的善用与否,成为程序效
能高低的关键技术。
& & 有些程序员不愿意精打细算,经常设定一些「缓冲器」,利用缓冲器可以任意定名、
便于记忆的优点,竟把珍贵的暂存器,当作各缓冲器间、搬运数据的交通工具,只见数
据不停的搬进搬出。虽然程序员省了点事,但运行速度白白浪费了,空间也被糟蹋了。
写这样的组合程序,远不如去用高级语言。
& & 当然,缓冲器是有必要的,但也只限于「必要」的情况,而且,在程序规划时,就
要考虑各种应用的条件,把缓冲器内的值取出后,一次处理完毕。如果不能一次解决或
是经常要用到的数据,则设法放在寄存器中。
& & 实际上,任何程序不可能在一个过程中,同时需要很多特殊的数据。好的程序员能
把复杂的工作处理得有条不紊,功力不够的,往往把简单的事情弄得令人难以理解。80
88的寄存器的确是不够用,但是却不至于少到要以缓冲器取代的地步。
& & 工作的好坏、成败,与人的组织能力有绝对的关系,限于篇幅,我们不能多谈。可
是,利用寄存器的特性,来处理繁杂的数据,倒也是训练组织力的方法之一。
& & 首先,我们应该把寄存器视为工具,了解工具的功能、性质,然后要能铭记于心,
纯熟地加以运用。
& & 根据个人的理解,寄存器概分六类:
& & 1,分段用
& && &程序段 CODE SEGMENT& && && && && & :CS
& && &数据段 DATA SEGMENT& && && && && & :DS
& && &堆栈段 STACK SEGMENT& && && && && &:SS
& && &特设段 EXTRA SEGMENT& && && && && &:ES
& & 2,堆栈用:
& && &堆栈值 STACK POINTER& && && && && &:SP
& && &栈用器 BASE POINTER& && && && && & :BP
& & 3,记忆转换用:
& && &源存器 SOURCE INDEX& && && && && & :SI
& && &终存器 DESTINATION INDEX& && && &&&:DI
& & 4,一般用:
& && &累积器 ACCUMULATOR& && && && && &&&:AX
& && &兼用器 BASE& && && && && && && && &:BX
& && &计数器 COUNTER& && && && && && && &:CX
& && &数据器 DATA& && && && && && && && &:DX
& & 5,标志用:旗号值 STATUS& && && && &&&:FLAG
& & 6,指示用:执行值 INSTRUCTION POINTER :IP
& & 为了便于记忆,我们给寄存器定中文名,其定义为:
& & 凡分段用者率称「段」,做为各段起始位置指示用,其计值方式为:系统中的绝对
地址=(本值×16)+各段寻址值
& & 如:数据段为 1600H,乘16即为16000H。
& & 如源存器为 1234H,则此源存器在系统中由0算起的地址为:17234H。
& & 应注意者,各种以「器」定名的暂存器,皆有限用的段,切勿混用。
& & 凡定名为「值」者,皆为不能用来供程序写作的暂存器。如堆栈值(SP)系指示堆
栈所在位置;旗号值(FLAG)表示旗号标志的情况;执行值(IP)则代表程序当前所执
行的地址。这些寄存器值并非不能改变,但对技巧尚不够纯熟者,最好保持原值,不要
& & 经常使用的「器」有两种,一以16位为单位,如栈用器、源存器及终存器; 另一种
则具有两个分别称「高位」及「低位」、各有8位,可单独使用,也可合并为16位的暂
存器AX,BX,CX,DX。
& & 寄存器通常作为容器用,但有些多用为记忆区之寻址,以便将其中贮存的数据取出
应用。前者称为容器功能,可以作计算、逻辑处理等。后者称为寻址功能,系供处理各
「器」所定地址的数据用。由于8088 CPU的寻址方式,受限于当初不成熟的设计理念,
偏偏 IBM独具慧眼,选中了它,所谓城门失火,殃及池鱼,读者不得不多花点功夫,小
& & 栈用器(BP)属于堆栈段的记忆位置,系提供给高级语言结构使用,对汇编语言来
说,功能不大,但若善于运用,也不无价值。
& & 源存器(SI)固定指向数据段,将源存器中的数据取出,所指的是取出数据段中的
数据。设若
& & DS=2000H& &SI=1234H,则
SI中的1234H 系指系统中 2000H×16加上地址值 1234H。
& & 不过,使用者不必去计算,只要知道是由数据段起,地址为1234H 即可。
& & 终存器(DI)较为复杂,通常它是指向数据段,可是有几个指令涉及大量数据转移,
需要由源存器搬到终存器。由于受限于分段的设计,为了便于段间应用,所以特别规定:
在这种情况下终存器系指向特设段(ES)。也就是说,只能由数据段移向特设段。程序
员可以先设定各段的段暂存器,再作转移。若要在同一段中作数据转移,则应使数据段
=特设段。
& & 一般用的暂存器,都可以分成两个8位、各命名为高、低位暂存器,如:
& & 累积器:AX&&高位 AH ,低位 AL
& & 兼用器:BX&&高位 BH ,低位 BL
& & 计数器:CX&&高位 CH ,低位 CL
& & 数据器:DX&&高位 DH ,低位 DL
& & 其中累积器的功能最强,可以做乘、除计算,AH尚有贮存旗号的特殊指令。尤其是
从记忆区中取值或将值放进记忆区内时,效率最高,如 LODS , STOSW等。
& & 由于其功能高,运用灵活,所以宜于打杂,千万不要赋与固定的使命。
& & 兼用器则有一种重要的特性,它是一般用寄存器中,唯一能自记忆区中读取数据者
(XLAT指令除外),所以作为「数据及寻址转换」 (后文将专门介绍此一功能) 方便异
& & 计数器常用作「回路」或次数的记录,也有专用的指令,除非不得已,或者计数用
得不多,最好保留备用。
& & 数据器功能最少,最好固定其用途,选择经常需要应用的数据,置放其中,以便发
挥时间空间的最高效率。
& && && && && && && && && && & 四、对指令的认识
& & 指令就是「指挥」、「命令」,用以控制计算机,一步一步地实现程序的计划。
& & 汇编语言的格式为:
& & ( 下行中凡标&[ ] &者,表有些指令可省略 )
& & [前置元]& &指令& &[目的操作元,源始操作元]
&&1,「前置元」:以下诸例即为前置元的用法。
& & 11段名:表后面的操作元应属于此临时前置段。如:
& && && & MOV& &&&AX,CS:BUF1
& & 12定义:表示其后缓冲器的临时定义。BYTE PTR表示以一个字符定义的数据; WORD
PTR表双字符数据。
& && && & 不论缓冲器的原定义为何,凡有前置元者,皆以临& && &时定义为准,如:
& && && & ADD& &&&BYTE PTR BUF1,CL
& && && & 前置元除了定义缓冲器长度外,亦可表示距离,
& && && & JMP& &&&SHORT ABCD
&&2,指令:
& & 11使用方法:
& && &1-1 寄存器到暂存器,但限长度相同者。
& && && & MOV& &&&AH,BL& &&&; 为字符
& && && & XCHG& & AX,BX& &&&; 为二字符
& && &1-2 寄存器到缓冲器,或缓冲器到暂存器。
& && && & OR& && &BUF1,AX& &; BUF1为缓冲器,WORD
& && && & ADD& &&&CL,BYTE PTR BUF1
& && &1-3 数值与寄存器或缓冲器之间。
& && && & TEST& & DI,8000H
& && && & AND& &&&SI,0FFH
& && && & SUB& &&&BYTE PTR BUF1,3
& && && & ★数值绝不可作为「目的」操作元
& && &1-4 将记忆区的地址放在寄存器中,以传送该地址的内容,或传送变量以便间接
调用数据。本法限用于源存器(SI)、终存器(DI)、栈用器(BP)及兼用器(BX)。如:
& && && & MOV& &&&AL,BYTE PTR [DI]
& && && & XOR& &&&[BP],DL
& && && & MOV& &&&AX,[DI][SI]
& && && & MOV& &&&AX,BUF1[DI]
& && && & JMP& &&&LAB1[BX]
& && &1-5 执行指令本身,不需源始或目的操作元。
& && && & PUSH& & CS
& && && & POP& &&&DS
& && && & CALL& & ABCD
& && && & JMP& &&&ABCD
& && && & CLI
& && && & STD
& && && & LAHF
& && && & RET
& && &1-6 执行计数者。
& && && & LOOP& & ABCD
& && && & REP& &&&MOVSB
& && && & SAL& &&&DL,CL
& && && & ROR& &&&AX,1
& && && & DEC& &&&BX
& && &1-7 寄存器专用指令。
& && && & OUT& &&&DX,AL
& && && & MUL& &&&BUF1
& && && & DIV& &&&CX
& && && & STOSB
& && && & LODSW
& && &1-8 条件执行者。
& && && & JNZ& &&&ABCD
& && && & JA& && &ABCD
& && && & JCXZ& & ABCD
& && && & INT& &&&10H
& && && & IRET
& & 12应用功能可分为下列八项:
& && &2-1 数据转移:1-1,1-2,1-3,1-4皆有可能。
& && &2-2 旗号控制:1-5 涉及旗号者。
& && &2-3 段址处理:1-1,1-2 项可能。
& && &2-4 数学计算:视指令而定,上述各项皆可。
& && &2-5 字符串处理:1-6,1-7 项功能。
& && &2-6 控制转换:1-5。
& && &2-7 条件执行:1-8。
& && &2-8 中断处理:1-8。
&&3,操作元:可分成暂存器、缓冲器及数值(Immediate Data)。其书写方式与习惯的
由前到后正好相反,使用时要小心,其余细节请参看有关汇编语言手册。
Powered by

我要回帖

 

随机推荐