我有一个课程的小项目,要求我们使用PIC汇编语言生成PWM信号。为了简化,我将高时间设置为5ms,低时间设置为15ms,这样我就可以多次调用同一个延迟子例程。多次调用此延迟似乎会导致堆栈下溢问题。
我真的不知道我可以尝试解决这个问题,因为我对编程非常新鲜。我已经尝试在这个网站上搜索,以及一般,但还没有能够找到一个解决方案。我正在使用MPLab 9.82以及。
代码如下:
list p=16F84A
#include <p16F84A.inc>
__CONFIG _CP_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF ;turn off watchdog timer
org 0x00 ; program starts at 0x00
counter equ 4Fh ; create a counter at position 4Fh in RAM
BSF STATUS, RP0 ; select bank 1
BCF TRISB, D'1' ; set port B pin 1 to output
BCF STATUS, RP0 ; select bank 0
goto main
main
BSF PORTB,1 ; turn port B pin 1 on
call delay_5ms ; calls sub routine for 5ms delay
BCF PORTB,1 ; turn port B pin 1 off
call delay_5ms ; calls sub routine for 5ms delay
call delay_5ms ; calls sub routine for 5ms delay
call delay_5ms ; calls sub routine for 5ms delay
delay_5ms
movlw D'200' ; put decimal number 200 into working register
movwf counter ; move 200 from working register into counter
lp nop ; no operation. just take 1 instruction
nop ; 1 instruction
decfsz counter ; 1 instruction and decreases counter by 1
goto lp ; 2 instructions (goto takes 2 instructions)
return
end
1条答案
按热度按时间kcwpcxri1#
正如Hans Passant所指出的,main需要有某种方法来防止fallthrough。为了详细解释这里发生的事情,让我们来看一个C函数:
虽然不是最好的例子,但我需要一个没有
return
语句的函数。至少,在C语言中没有return
语句,但在汇编语言中,这个函数(假设它没有被内联)看起来像这样:用C编写的函数将始终编译为带有 *return指令 * 的汇编函数(除非编译器内联该函数),即使您的函数没有C
return
语句。为什么需要这样做?因为ASM标签不存在。
程序集源文件中带标签的代码行只是对特定内存地址的引用。
goto main
只是一个硬件抽象,意思是“后藤whatever memory address main碰巧是什么。分支是相对的还是绝对的,这无关紧要--汇编程序为您进行计算,并将goto main
中的main
替换为所需的偏移量,以使分支将您带到所需的位置。然而,当创建可执行文件时,main:
(注意后面的冒号,我指的是标签本身)没有了。这导致了汇编语言中的一些怪癖,而这些怪癖在其他语言中不会发生:第二,也是最重要的一点,没有什么可以阻止执行通过标签。
完全一样
也就是说,如果你想执行某个函数固定的次数,而没有循环的开销,你可以使用fallthrough。