应用电子威廉希尔官方网站
IncorrectTableLookup: move dp[0], #w:StartOfTable move acc, @dp[0] . . . ret . . . StartOfTable: dc16 01234h dc16 05678h dc16 098abh dc16 0cdefh上述代码能很顺利地完成汇编,但是执行完第二条指令之后,累加器的值几乎不可能是0x1234。原因很简单,Von Neumann结构只有一个单独的存储空间,一条指令根据操作的需要可能花费多个指令周期,而MAXQ与此不同,其move
BetterTableLookup: move dp[0], #w:StartOfTable + 08000h call UtilityROMGetDP0 . . . ret . . . StartOfTable: dc16 01234h dc16 05678h dc16 098abh dc16 0cdefh在本例程中,调整待读取的地址,以反映执行固定用途ROM程序时闪存的映射地址,然后将其装入DP[0]。这里采用了调用固定用途ROM程序的方法,而不是直接读取数据。当然,直接读取数据只占用一个指令周期,而这一操作则占用了四个指令周期:2个周期用于长调用,1个周期用于读取数据,1个周期用于返回操作。
org 0800Dh dw UtilityFunctionTable . . . UtilityFunctionTable: . . . dw GetDP0 dw GetDP0Inc dw GetDP0Dec dw GetDP1 dw GetDP1Inc dw GetDP1Dec dw GetBP dw GetBPInc dw GetBPDec注意:第一,固定用途函数表由地址组成,而不是指令。因此,编程人员必须提取地址并call它,而不能简单地跳转至该表。第二,第一个存储器函数也许不是该表的入口。由于每款MAXQ微控制器包含不同类型和容量的存储器以及不同的外设,每款器件很有可能包含不同的函数列表,函数在表中具有不同的相对偏移量。
CorrectTableLookup: move dp[0], #0800Dh ; Point to pointer to function table move acc, @dp[0] ; acc now has pointer to ftable add #3 ; For 2000, GetDP0 move dp[0], acc ; Load ptr + offset to dp0 move a[1], @dp[0] ; Get address of GetDP0 into A1 move dp[0], #StartOfTable + 08000h call a[1] ; This will call GetDP0, finally! . . . ret . . . StartOfTable: dc16 01234h dc16 05678h dc16 098abh dc16 0cdefh需注意,一旦找到GetDP0程序的地址,即可将该地址存放起来并重复使用。上述前5条指令只需要执行一次;然后,每次访问表数据操作只需要三个指令周期:调用,读取(运行固定用途ROM内的程序),返回(也运行固定用途ROM内的程序)。
SlowTableMove: move dp[0], #0800Dh ; Point to pointer to function table move acc, @dp[0] ; acc now has pointer to ftable add #4 ; For 2000, GetDP0Inc move dp[0], acc ; Load ptr + offset to dp0 move a[1], @dp[0] ; Get address of GetDP0 into A1 move dp[0], #StartOfTable + 08000h move bp, #RAMDest ; Set this label to desired dest move offs, #0ffh ; Pre-decremented offset move lc[0], #4 ; Move four words TableMoveLoop: move dp[0], dp[0] ; Set source pointer call a[1] ; This will call GetDP0inc move @bp[++offs], gr ; Store retrieved word to dest djnz lc[0], TableMoveLoop . . . ret . . . StartOfTable: dc16 01234h dc16 05678h dc16 098abh dc16 0cdefh如上文所述,前5条指令只需要执行一次,此后可根据需要多次执行表操作,GetDP0inc子程序地址始终保存在A1中。每次执行表操作需要6个指令周期外加建立开销。
FasterTableMove: move dp[0], #0800Dh ; Point to pointer to function table move acc, @dp[0] ; acc now has pointer to ftable add #12 ; For 2000, copyBuffer move dp[0], acc ; Load ptr + offset to dp0 move a[1], @dp[0] ; Get address of GetDP0 into A1 move dp[0], #StartOfTable + 08000h move bp, #RAMDest ; Set this label to desired dest move offs, #0 ; No need to pre-decrement offset move lc[0], #4 ; Move four words call a[1] ; This will call copyBuffer . . . ret . . . StartOfTable: dc16 01234h dc16 05678h dc16 098abh dc16 0cdefhcopyBuffer程序将每次表操作的周期数减至3个,比之前提到的方法节省了约一半时间。当从copyBuffer程序返回时,LC[0]清零,OFFS寄存器指向最近一次写目标地址的下一个位置。因为OFFS是一个8位寄存器,因此用这种方法可以拷贝多达256字的表。
; ; Output String ; ; Enter with ACC=an index value (one based) indicating which ; string to output. ; ; On exit, LC0=0, DPC=0, ACC, A1, A2, DP0 used. ; output_string: move lc[0], acc ;Set LC0 to index of string move dpc, #4 ;Set DP0 to word mode move dp[0], #800dh ;Point to table of pointers move acc, @dp[0] ;Get address of table add #3 ;Offset to GETDP0 routine move dp[0], acc ;Load pointer to table move a[1], @dp[0]++ ;Get GETDP0 move a[2], @dp[0] ;Get GETDP0INC move dpc, #0 ;Set DP0 to byte mode move dp[0], #string_table + 8000h str_search_loop: call a[1] ;Get a string length djnz lc[0], next_str ;If not this string, go to next move lc[0], gr ;Otherwise, put len in LC0 move acc, @dp[0]++ ;...and point past length out_loop: call a[2] ;Get a char and bump pointer call char_out ;Output the character djnz lc[0], out_loop ;If more characters, loop ret ;Otherwise, we're done. next_str: move acc, gr ;GR contains len of this string add dp[0] ;Add current ptr to current len... move dp[0], acc ;...to create a new pointer jump str_search_loop ;Jump back and test index again ; ; Each entry in the string table begins with the string length ; followed by the string characters. ; string_table: dc8 string1 - string_table dc8 "This is the first string." string1: dc8 string2 - string1 dc8 "This is a second example of a string" string2: dc8 string3 - string2 dc8 "A third string." string3: dc8 string4 - string3 dc8 "Finally, a fourth string in the array!!!" string4:
全部0条评论
快来发表一下你的评论吧 !