assembly 汇编代码抛出堆栈溢出错误,我找不到原因

ssm49v7z  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(109)

我正在为一个课程做一个项目,我必须在汇编中编写一些程序,我正在使用PIC 16F887,我知道它有一个8级堆栈,我找不到为什么/在哪里我会在它上面。
代码看起来像这样:

targ_temp   EQU 0x20        
CONT1       EQU 0x20
CONT2       EQU 0x21
TTEMPU      EQU 0x22
TTEMPD      EQU 0X23
aux     EQU 0X24
FLAGS       EQU 0X25
TEMPU       EQU 0X26
TEMPD       EQU 0X27
PESO        EQU 0X28
CONT        EQU 0X30

;**********************************************************************
        
    ORG     0x000             
    goto    main              
    ORG     0x004             
    BTFSC INTCON,2
    CALL TIMEROVERFLOW
    BTFSC INTCON,1
    CALL SENSORVASO
    BTFSC INTCON,0
    CALL LEERTECLADO
    BTFSC PIR1,6
    CALL CONVERSOR
    ;BTFSC PIR1,5
    ;CALL EUSARTRECIEVE
    ;BTFSC PIR1,4
    ;CALL EUSARTTRANSMIT
    // clearing flags
    retfie                    ; return from interrupt
main
    //setup
    GOTO $
LEERTECLADO                       ;polling the keypad
    call DELAY
    movlw 0x0F
    iorwf PORTC,1
    MOVLW 0XFF    ;I use this to check at the end if a button is actually pressed, or if it was let go/pressed some other key that I'm not mapping
    BCF PORTC,3
    BTFSS PORTB,7 ;<- this is where the stack overflow originates from
    movlw 0x1
    BTFSS PORTB,6
    movlw 0x2
    BTFSS PORTB,5
    movlw 0x3
    BTFSS PORTB,4
    goto tempres
    clrf PORTC
    bsf PORTC,3
    bcf PORTC,2
    BTFSS PORTB,7
    movlw 0x4
    BTFSS PORTB,6
    movlw 0x5
    BTFSS PORTB,5
    movlw 0x6
    BTFSS PORTB,4
    goto tempset
    clrf PORTC
    BSF PORTC,2
    BCF PORTC,1
    BTFSS PORTB,7
    movlw 0x7
    BTFSS PORTB,6
    movlw 0x8
    BTFSS PORTB,5
    movlw 0x9
    clrf PORTC
    BSF PORTC,1
    BCF PORTC,0
    BTFSS PORTB,6
    movlw 0x0
    BCF PORTC,3
    BCF PORTC,2
    BCF PORTC,1
    BCF PORTC,0
    addlw 0x1           ;here I check if w overflows, if it does it means no buttons were pressed
    btfsc STATUS,2      ;
    goto term           ;
    sublw 0x1           ;if it didn't overflow I bring it back to the original value
    movwf aux
    movf TTEMPU,0
    movwf TTEMPD
    movf aux,0
    movwf TTEMPU
    goto term
tempset movlw 0X26
    movwf FSR
    BCF PORTA,7
    BSF PORTA,6
    BCF STATUS,7
    BCF STATUS,6
    goto term
tempres clrf TTEMPU
    clrf TTEMPD
    MOVLW 0x22
    movwf FSR
    BCF PORTA,7
    BSF PORTA,6
    BCF STATUS,7
    BCF STATUS,6        
term    return
CONVERSOR   
    BTFSC FLAGS,6
    GOTO SERV
    CLRF TEMPD
    CLRF TEMPU
    MOVLW .25
adec    SUBWF ADRESH,1
    INCF TEMPD,1
    BTFSC STATUS,0
    GOTO over
    BTFSS STATUS,2
    GOTO adec
    GOTO tempter
over    DECF TEMPD,1
    ADDWF ADRESH,1
    MOVLW .10
    SUBWF TEMPD,0
    BTFSC STATUS,2
    GOTO cien
    MOVLW .3
aun SUBWF ADRESH,1
    INCF TEMPU,1
    BTFSC STATUS,0
    GOTO overun
    BTFSS STATUS,2
    GOTO aun
    GOTO tempter
overun  DECF TEMPU,1    
    GOTO tempter
cien    MOVLW .10
    MOVWF TEMPD
    CLRF TEMPU
    BCF PORTA,4
    GOTO FINADC
tempter MOVF TEMPD,0
    SUBWF TTEMPD,0
    BTFSC STATUS,0
    GOTO apagar
    BTFSS STATUS,2
    GOTO mant
    MOVF TEMPU,0
    SUBWF TTEMPU,0
    BTFSC STATUS,0
    GOTO apagar
    BTFSS STATUS,2
    GOTO apagar
mant    BSF PORTA,4
    BCF FLAGS,7
    GOTO FINADC
apagar  BCF PORTA,4
    BSF FLAGS,7
    GOTO FINADC
SERV    
    MOVLW PESO
    SUBWF ADRESH,0
    BTFSC STATUS,0
    GOTO VLLENO
    BTFSS STATUS,2
    GOTO VLLENO
    GOTO FINADC
VLLENO  BCF FLAGS,6
    BCF PORTA,5
    BCF ADCON0,3
    INCF CONT,1
    MOVFW CONT
    BANKSEL TXREG
    MOVWF TXREG
    BSF TXSTA,5
    BANKSEL CONT
FINADC  BSF ADCON0,1
    RETURN
SENSORVASO
    call DELAY
    BTFSS FLAGS,7
    GOTO ENDVASO
    BSF PORTA,5
    BSF FLAGS,6
    BSF ADCON0,3
ENDVASO return
TIMEROVERFLOW   
    btfsc PORTA,7
    goto inver
    incf FSR,1
    movf INDF,0
    call TABLA
    movwf PORTD
    BCF PORTA,6
    BSF PORTA,7
    goto termi
inver   
    DECF FSR,1
    movf INDF,0
    call TABLA
    movwf PORTD
    BCF PORTA,7
    BSF PORTA,6
termi   
    return
TABLA
    ADDWF PCL,F 
    RETLW b'11111100'   ;devuelve 0
    RETLW b'01100000'   ;1
    RETLW b'11011010'   ;2
    RETLW b'11110010'   ;3
    RETLW b'01100110'   ;4
    RETLW b'10110110'   ;5
    RETLW b'10111110'   ;6
    RETLW b'11100000'   ;7
    RETLW b'11111110'   ;8
    RETLW b'11110110'   ;9
    RETLW b'11111010'   ;.0
DELAY                       ;delay routine mainly for debouncing 
    movlw .3
    movwf CONT2
ext
    movlw .250
    movwf CONT1
int
    decfsz CONT1,1
    goto int
    decfsz CONT2,1
    goto ext
    return
    END

请原谅西班牙语的标签,我得到一个堆栈溢出警告时模拟在proteus和触摸按钮连接RB7和RC3,也实现了它在一个试验板和有(我相信)同样的事情发生,这意味着从我可以看到的显示停止切换,只有一个会卡住与相同的值显示无论我做了什么。
我正在使用proteus检查一切是否按照预期工作,然后将其移动到董事会,直到我遇到这个。它启动的确切错误是:[PIC16 CORE] PC = 0x00E9。执行CALL指令的堆栈溢出。[U1]我尝试使用异步刺激在MPLAB X上进行调试,我逐行跟踪代码,它按预期工作。我在另一个论坛上读到的一件事是,tabla中添加的值(将其添加到pc)可能是负的,它可能会以这种方式进入另一个调用并溢出,但我看不到这里发生,因为它是中断上的一段代码,所以它不能被缩短,它要么放置一个0 - 9之间的值,要么返回。我会留下一些我认为没有必要的代码,但可能有什么我没有看到。我不知道该怎么办

xnifntxz

xnifntxz1#

堆栈溢出发生在TIMEROVERFLOW函数/例程中,我不能证明为什么,但使用指针和间接寻址发送了一个错误的W reg值调用TABLA,这导致pc去了它不应该去的地方,即使我在设置中初始化值为0。我用一个标志替换了这个例程,它检查我试图显示的内容,而不是依赖于指针,这样我就不会再出现堆栈溢出。

ffvjumwh

ffvjumwh2#

是的,看起来你只使用了三个级别(中断本身,对特定处理函数的调用,以及其中一些对延迟的调用)(1)。
我所能建议的是,首先找出哪段代码位于0x00e9,即堆栈溢出错误消息中列出的地址。这可能会提供一个线索。
然后,也许在TABLA的开头放置一些保护代码,以便它只对特定的可接受值进行添加。如果没有,请执行其他操作,例如选择默认值或输入另一个无限循环(如main: goto $循环)。希望您可以通过地址总线上永不改变的PC来获取它。
在我看来,这似乎是唯一一个在你正常(三级)途径之外的召唤载体。例如,addw pcl, f * 可能 * 最终有效地跳回到中断例程中的某个地方,并再次调用其中一个处理函数。这样做几次,砰,你的堆栈耗尽了。
根据模拟器的性能,您可以跟踪程序计数器的每个值并查看它的去向。
(1)在线调试器可能会增加另一个级别,但这 * 仍然 * 只有4个,远远低于16F877的8个限制。

相关问题