直接定址表02 - 零基础入门学习汇编语言73
2011-06-02 23:59
573 查看
第十六章:直接定址表02
让编程改变世界Change the world by program
直接定址表
这一节课,我们将讨论用“查表”的方法编写相关程序的技巧。任务:编写子程序,以十六进制的形式在屏幕中间显示给定的byte 型数据。
小小分析
一个字节需要用两个十六进制数码来表示,所以,子程序需要在屏幕上显示两个ASCII 字符。我们当然要用“0”、“1”、“2”、“3”、“4”、“5” 、“6” 、“7” 、“8” 、“9” 、“A”、“B”、“C”、“D”、“E”、“F”这16个字符来显示十六进制数码。
我们可以将一个byte的高4位和低4 位分开,分别用它们的值得到对应的数码字符。比如 2Bh ,我们可以得到高4 位的值为2,低4 位的值为11。
那么我们如何用这两个数值得到对应的数码字符“2”和“B”呢?我知道,我们一看就知道是 2和 B ,但CPU 是 SB, 它不懂,它只懂 1 和 0。
最简单的办法就是一个一个地比较,如下:
如果数值为 0,则显示“0”;
如果数值为 1,则显示“1”;
:
如果数值为15,则显示“F”;
我们可以看出,这样做,程序中要使用多条比较、转移指令。程序将比较长,混乱。
显然,我们希望能够在数值0~15和字符“0 ~ F”之间找到一种映射关系。这样我们用0~15间的任何数值,都可以通过这种映射关系直接得到“0”~“F”中对应的字符。
数值0~9和字符“0”~“9”之间的映射:
数值 + 30h = 对应字符的ASCII值:
0+30h = “0”的ASCII值
1+30h = “1”的ASCII值
:
但是,10~15和“A”~“F”之间的映射关系是:
数值+37h=对应字符的ASCII值:
10+37h=“A”的ASCII值
11+37h=“B”的ASCII值
12+37h=“C”的ASCII值
:
可见,我们是利用数值和字符之间的这种原本存在的映射关系,通过高 4 位和低4 位值得到对应的字符码。但我们发现一个问题……
但是由于映射关系的不同,我们在程序中必须进行一些比较,对于大于 9 的数值,我们要用不同的计算方法。
这样做,虽然使程序得到了简化。但是,如果我们希望用更简捷的算法,就要考虑用同一种映射关系从数值得到字符码。
所以,我们就不能利用0~9和“0”~“9” 之间与 10~15 和 “A” ~“F ” 之间原有的映射关系。因为他们有两个映射关系,不满足我们的条件。
具体的做法是,我们建立一张表,表中依次存储字符“0”~“F”,我们可以通过数值0~15直接查找到对应的字符。
子程序实现代码:相关代码下载
可以看出,在子程序中,我们在数值0~15和字符“0”~“F ” 之间建立的映射关系为:以数值N为table 表中的偏移,可以找到对应的字符。
利用表,在两个数据集合之间建立一种映射关系,使我们可以用查表的方法根据给出的数据得到其在另一集合中的对应数据。
这样做的目的一般来说有三个:
(1)为了算法的清晰和简洁。(2)为了加快运算速度。
(3)为了使程序易于扩充。
在刚刚的子程序中,我们更多的是为了算法的清晰和简洁,而采用了查表的方法。
下面我们来看一下,为了加快运算速度而采用查表的方法的情况。
任务二:
编写一个子程序,计算sin(x),x∈{0°,30°,60°,90°,120°,150°,180°},并在屏幕中间显示计算结果。
例如sin(30) 的结果显示为“0.5”。我们可以利用麦克劳林公式来计算sin(x)。
x 为角度,麦克劳林公式中需要代入弧度,则:
。。。。。。
y=x/180*3.1415926
可以看出,计算sin(x)需要进行多次乘法和除法。乘除是非常费时的运算,它们的执行时间大约是加法、比较等指令的5倍。
那么我们如何才能够不做乘除而计算sin(x)呢?
我们看一下需要计算的sin(x)的结果:
sin(0)=0
sin(30)=0.5
sin(60)=0.866
sin(90)=1
sin(120)=0.866
sin(150)=0.5
sin(180)=0
我们可以看出,其实用不着计算,可以占用一些内存空间来换取运算的速度。
将所要计算的sin(x) 的结果都存储到一张表中;然后用角度值来查表,找到对应的sin(x)的值。
我们用 ax 向子程序传递角度。
演示代码:相关代码下载
在上面的子程序中,我们在角度值x和表示 sin(x) 的字符串集合table 之间建立的映射关系为:
以角度值 /30 为table 表中的偏移,可以找到对应的字符串的首地址。
编程的时候要注意程序的容错性,即对于错误的输入要有处理能力。
在上面的子程序中,我们还应该在加上对提供的角度值是否超范围的检测。
如果提供的角度值不在合法的集合中,程序将定位不到正确的字符串,出现错误。
对于角度值的检测,大家请自行完成。
上面的两个子程序中,我们将通过给出的数据进行计算或比较而得到结果的问题,转化为用给出的数据作为查表的依据,通过查表得到结果的问题。
具体的查表方法 ,是用查表的依据数据 ,直接计算出所要查找的元素在表中的位置。
像这种可以通过依据数据,直接计算出所要找的元素的位置的表,我们称其为:直接定址表。
我们可以在直接定址表中存储子程序的地址,从而方便地实现不同子程序的调用。
[buy] 获得所有教学视频、课件、源代码等资源打包 [/buy]
[Downlink href='http://kuai.xunlei.com/d/LLTBSDESGFXP']视频下载[/Downlink]
相关文章推荐
- 直接定址表02 - 零基础入门学习汇编语言73
- int指令02 - 零基础入门学习汇编语言65
- 内中断02 - 零基础入门学习汇编语言61
- 包含多个段的程序02 - 零基础入门学习汇编语言30
- 转移指令的原理02 - 零基础入门学习汇编语言44
- 转移指令的原理02 - 零基础入门学习汇编语言44
- 数据处理的两个基本问题02 - 零基础入门学习汇编语言39
- 直接定址表03 - 零基础入门学习汇编语言74
- 寄存器(内存访问)02 - 零基础入门学习汇编语言14
- 数据处理的两个基本问题02 - 零基础入门学习汇编语言39
- 直接定址表03 - 零基础入门学习汇编语言74
- 寄存器(内存访问)02 - 零基础入门学习汇编语言14
- Call指令和Ret指令讲解02 - 零基础入门学习汇编语言49
- Call指令和Ret指令讲解02 - 零基础入门学习汇编语言49
- 第一个程序02 - 零基础入门学习汇编语言21
- 外中断02 - 零基础入门学习汇编语言70
- 使用BIOS进行键盘输入和磁盘读写02 - 零基础入门学习汇编语言76
- 第一个程序02 - 零基础入门学习汇编语言21
- 外中断02 - 零基础入门学习汇编语言70
- 使用BIOS进行键盘输入和磁盘读写02 - 零基础入门学习汇编语言76