我有一个PIC18F25K50混合C和组装项目;我想做的大部分工作都可以在Assembly中轻松管理(并且必须提高效率),但有些部分我更关心开发的易用性。我实际上有几个这样的部分,我一直遇到同样的问题:我无法使用ASM跳转到标签。如果给出一个标签,将每个要跳转的函数CALL
,GOTO
,BNC
等等都会失败,将PC设置为某些随机但一致的值,其中没有指令,导致程序挂起。使用地址可以正常工作:BC $+4
跳过下一行。
不起作用的一个例子是:
#asm
_waitUS:
GLOBAL _waitUS
waitLoop:
//12 cycles = 1 microsecond:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ WREG, F, ACCESS
GOTO waitLoop
RETURN
#endasm
void main() {
//DEBUG:
waitUS(6);
}
现在,这可能无法全面发挥作用,而且我乞求你专注于跳跃问题 - 这仍然是原型设计,因为我甚至无法获得调用的函数。该程序确实编译没有问题。
一旦waitUS(6)
被调用,PC就会从 - 0x7C96
跳到0x52
。MOVLW 6; CALL _waitUS
。以完全相同的方式交换C呼叫0x7C92
中断。
如果我严格使用C进行呼叫/跳转(正如我在之前的项目中所做的那样),它运行正常,并找出它的去向。
我几个星期以来一直在寻找这个问题的答案,并且仍然没有看到其他人遇到过这个问题,即使我做的每个项目(包括记事本中的明文,通过命令行编译)都有完全相同的问题。这到底是怎么回事?
编辑:在发现程序内存视图后,我能够更好地了解它正在做什么。编译器 知道函数的位置,并且 试图跳转到正确的位置。显然,CALL只是不知道它的发展方向。
实施例:
地址CALL 0x2044, 0
包含PC
。这恰恰是应该的,也就是期望的功能开始的地方。但是,运行此指令后,0x205E
会更改为 0x205E ,缺少一半的功能。
为了变得聪明,我决定在标签之后将几个NOP添加到函数的开头,用0x2086
填充实际代码。不幸的是,似乎任何改变都会改变其不可预测的跳跃落地的地方,然后它会降落在GOTO
处。
顺便提一下,当它开始在随机位置运行时,它通常会在GOTO
上运行 - 并且 将按预期跳转到指定位置。这仅适用于同一个函数,因为尽管编译结果需要,但尝试使用CALL
而不是{{1}}最终会出现在同一个错误的位置。
答案 0 :(得分:0)
the .pdf document at:
<http://ww1.microchip.com/downloads/en/DeviceDoc/33014K.pdf>
has many examples on how to code the PIC18.
Here is one such example:
RST CODE 0x0 ;The code section named RST
;is placed at program memory
;location 0x0. The next two
;instructions are placed in
;code section RST.
pagesel start ;Jumps to the location labelled
goto start ;’start’.
PGM CODE ;This is the beginning of the
;code section named PGM. It is
;a relocatable code section
;since no absolute address is
;given along with directive CODE.
start
movlw D'10'
movwf delay_value
xorlw 0x80
call delay
goto start
end