我正在努力实现一个函数跳转表,希望有人能帮忙。
这是我尝试过的代码示例之一,但没有成功。 看起来,当调用跳转表时,程序就进入了太空。这是对函数的设置和调用,该函数旨在设置跳转表调用。
; call the next routine
movlw 1 ; this should call the second function
movwf programIndex
call runCurrentProgram
这里是应根据programIndex 值设置PC 的位置。我不确定是否需要乘数。 当我查看表汇编输出时,它似乎只有 2 个单词,因此乘数似乎没有必要。
runCurrentProgram:
bcf programIndex, 7 ; clear high bit for rotate
rlf programIndex, W ; multiply index by two
addlw low programTable
movwf tabLow ; tabLow is a temporary variable
movlw high programTable
btfsc STATUS,STATUS_CARRY_POSITION
addlw 1
movwf PCLATH
movf tabLow,w
movwf PCL
最后,这是我定义跳转表的方式。
programTable:
goto Function1
goto Function2
如前所述,Function1 和 Function2 都包含在单独的库中。 如果直接从控制程序调用,它们就可以正常工作。
我发现了几个类似代码的示例,使用 goto、BRA 或 BRW,但没有一个是专门针对 PIC16F1503 的,并且对我不起作用。
有人可以帮我吗?
感谢@TimRoberts 的建议。 换成DW也没用。 用 BRA 替换确实有效。 我仍在尝试了解 PCL、PCLATH 代码的使用,但我可以清楚地看到(从列表中)DW 已呈现绝对地址,即链接器分配给函数的地址,而 BRA 生成其他内容。
列表显示 Function1 加载于 014B,Function2 加载于 016F,使用 DW 和 BRA 生成的代码如下所示。
340 0100 324A bra Function1
341 0101 326D bra Function2
340 0100 014B dw Function1
341 0101 016F dw Function2
我还做了一些实验,通过使用其中一个函数的绝对地址(从汇编器/链接器列表中获得)加载 PCLATH 和 PCL 来更好地理解 PCL,并且能够让自己满意,只要 PCLATH 设置为正确的寄存器Bank,并将PCL设置为bank中的函数地址,然后一切正常。 我现在将花更多时间研究动态表条目选择代码。
我有以下工作代码,它使用 BRA 跳转到所需的函数(使用其相对地址)。在构建中使用链接器选项 -pprogramTable=100h 将跳转表定位在 0x100。
; The jump table is located on the start of a page boundary 0x100
global programTable
psect programTable,global,class=CODE,delta=2
programTable:
bra f1
bra f2
bra f3
bra endOfTable
endOfTable: ; reset the index back to start of table
clrf programIndex
return
这是使用跳转表的代码。
runCurrentProgram:
movf programIndex,w
addlw low programTable
movwf tabLow ; tabLow is a temporary variable
movlw high programTable
btfsc STATUS,STATUS_CARRY_POSITION
addlw 1
movwf PCLATH
movf tabLow,w
movwf PCL