代码改变世界

Freescale MC9S08AW60汇编学习笔记(五)

2015-04-30 20:51  赤骥~  阅读(336)  评论(0编辑  收藏  举报

  前面学习了查表的功能,可以用查表的功能实现不少强大的功能,如查立方表、平方表、函数表、数码管显示的段码表等。这里还有一种由查表和转移指令配合使用而实现的一种强大的功能:散转。散转是指根据输入数据的不同来跳转到不同的程序入口进行处理,也就是说如果有多个子程序,我们不仅可以让它们按顺序一个个执行,还可以根据做判断用的数据的值来决定跳转到哪一个子程序。实现散转的具体做法是:在程序中定义一块连续存储单元作为跳转表,表中顺序存放各分支处理程序的跳转地址。各跳转地址在表中的偏移地址等于跳转表首地址加上它们各自的序号所占字节数的乘积。感觉关于跳转地址这一块有点不好理解,就用一个例子来说明一下:

  设字节变量Num的取值范围为0~3,另有程序入口地址Pro0~Pro3,编写子程序,要求根据Num的值转向不同的Pro程序。如Num为2则转向Pro2。代码如下:

 org $0070
Num ds.b 1

 org $1860

Pro0:nop                    ;子程序群,这里都让他们空操作。
   rts
Pro1:nop
   rts
Pro2:nop
   rts
Pro3:nop
   rts

Sbranch:                   ;分支程序,有点像c语言中switch
  ldx Num              ;Num-->X
  lda #05h        
  mul                     ;Num*5-->X:A
  tax                      ;A-->X  
  clrh                     ;查表之前别忘清零
  jmp Pro_Tab,x

Pro_Tab:                   ;跳转表
  jsr Pro0               ;跳转到Pro0,3B
  bra Sb_End          ;调用Pro0完毕,返回,2B

  jsr Pro1
  bra Sb_End

  jsr Pro2
  bra Sb_End

  jsr Pro3
Sb_End: rts

main:
  clra
  clrx
  clrh

  mov #$01,Num     ;设定Num的值,用来作为选择子程序的判断数

  bsr Sbranch


again:
  nop
  jmp again


 org $fffe
 dc.w main

  细心的人肯定会发现Num是先乘以5之后才用来做散转的,其原因在于Pro_Tab标号后面的JSR指令是3字节指令,BRA指令值2字节指令,故数值Num、标号Pro_Tab的地址Addr_Pro和指令语句JSR  Pro_n的首地址Addr_Pro_n之间的关系为:

                         Address_Pro_n=Addr_Pro+Num*5

  是不是突然发现汇编的强大了,从一开始汇编给人的感觉是在寄存器之间跳来跳去变成了汇编可以实现这个功能那个功能,只要设计足够精巧、心思足够细腻,就算是汇编这种呆板的机器语言也可以焕发勃勃生机,举个例子:MenuetOS是一款完全用汇编语言写成的操作系统。 因此它运行起来超快,体积也非常小,它甚至可以放在一张软盘内。MenuetOS提供了抢占式多任务处理,一个引人注目的漂亮GUI,用于网络接入的 TCP/IP堆栈等等。由此可见:强大的不是工具而是人。当然,如果强大的工具加强大的人必然可以爆发出惊人的力量。