Assembly 为什么微控制器会出现堆栈溢出问题?

Assembly 为什么微控制器会出现堆栈溢出问题?,assembly,stack-overflow,microcontroller,pic,Assembly,Stack Overflow,Microcontroller,Pic,我将解释我在汇编和使用pic 16f84a编程时遇到的问题,我在讨论表格管理和跳转,我必须在显示器上显示一个字母,字符是我定义的常量,例如字母“p”,所以我认为我的程序应该可以工作,但当我在Proteus中模拟它时,这给了我一个堆栈溢出问题,但是如果我使用一个辅助内存空间并将字母保存在其中,程序工作正常,因此我无法理解为什么我需要一个辅助内存空间来保存我之前声明过的字母,我认为它已经存储在内存空间中,我还要说,因为它是一个常数,所以我没有修改它,我只是用它做减法 ;THIS CODE PRESE

我将解释我在汇编和使用pic 16f84a编程时遇到的问题,我在讨论表格管理和跳转,我必须在显示器上显示一个字母,字符是我定义的常量,例如字母“p”,所以我认为我的程序应该可以工作,但当我在Proteus中模拟它时,这给了我一个堆栈溢出问题,但是如果我使用一个辅助内存空间并将字母保存在其中,程序工作正常,因此我无法理解为什么我需要一个辅助内存空间来保存我之前声明过的字母,我认为它已经存储在内存空间中,我还要说,因为它是一个常数,所以我没有修改它,我只是用它做减法

;THIS CODE PRESENTS THE STACK OVERFLOW PROBLEM
;CONFIG ZONE
          __CONFIG  _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC
          LIST      P=16F84A
          INCLUDE   <P16F84A.INC>
         
Character EQU       'P'                 ;DECLARATE AND SAVE THE LETTER 'P' AS A CONSTANST
;CODING ZONE
          ORG       0      
          
Start
          bsf       STATUS, RP0         ;MOVE TO BANK 1           
          clrf      PORTB               ;DECLARATE PORTB AS OUTPUT    
          bcf       STATUS, RP0         ;MOVE TO BANK 0
          
Main
          movlw     'A'                 ;MOVE THE LETTER 'A' TO W REGISTER
          subwf     Character, W        ;REMANDEIR THE HEXADECIMAL VALUE OF 'P' AND 'A', AND SAVE IT IN THE W REGISTER
          call      LetterTo7Segments   ;CALL A SUBROUTINE   
          movwf     PORTB               ;SHOW THE VALUE OF THE LETTER IN DISPLAY          
          goto      Main
          
LetterTo7Segments          
          addwf     PCL,F               ;ADD THE VALUE OF THE REGISTER W TO PROGRAM COUNTER, TO JUMP TO ONE OF THE INSTRUCTIONS
                                        ;AND RETURN THE HEXADECIMAL VALUE INSIDE THE W REGISTER
          DT        77h, 7Ch, 39h, 5Eh, 79h, 71h, 6Fh, 76h, 19h, 1Eh, 7Ah, 38h, 37h
          DT        54h, 3Fh, 73h, 67h, 50h, 6Dh, 78h, 1Ch, 3Eh, 1Dh, 70h, 6Eh, 49h
          END
;此代码表示堆栈溢出问题
;配置区
__配置CP关闭和WDT关闭和PWRTE打开和OSC
列表P=16F84A
包括
字符等于'P';声明并将字母“P”另存为常量
;编码区
组织0
开始
bsf状态,RP0;搬到1号银行
clrf端口B;将PORTB声明为输出
bcf状态,RP0;移动到银行0
主要的
movlw'A';将字母“A”移动到W寄存器
subwf字符,W;重新定义“P”和“A”的十六进制值,并将其保存在W寄存器中
呼叫7段;调用子程序
movwf-PORTB;在显示中显示字母的值
后藤大街
字母7段
addwf PCL,F;将寄存器W的值添加到程序计数器,以跳转到指令之一
;并返回W寄存器中的十六进制值
DT 77h、7Ch、39h、5Eh、79h、71h、6Fh、76h、19h、1Eh、7Ah、38h、37h
DT 54h,3Fh,73h,67h,50h,6Dh,78h,1Ch,3Eh,1Dh,70h,6Eh,49h
终止
;这个代码工作正常
;配置区
__配置CP关闭和WDT关闭和PWRTE打开和OSC
列表P=16F84A
包括
字符等于'P';声明并将字母“P”另存为常量
辅助设备0x0D;声明内存空间
;编码区
组织0
开始
bsf状态,RP0;搬到1号银行
clrf端口B;将PORTB声明为输出
bcf状态,RP0;移动到银行0
主要的
movlw字符;将字符的值移动到W寄存器
movwf-Aux;将W(字母)的值保存在名为AUX的内存空间中
movlw'A';将字母“A”移动到W寄存器
副世界银行,W;重新读取AUX(字母)和“A”的十六进制值,并将其保存在W寄存器中
呼叫7段;调用子程序
movwf-PORTB;在显示中显示字母的值
后藤大街
字母7段
addwf PCL,F;将寄存器W的值添加到程序计数器,以跳转到指令之一
;并返回W寄存器中的十六进制值
DT 77h、7Ch、39h、5Eh、79h、71h、6Fh、76h、19h、1Eh、7Ah、38h、37h
DT 54h,3Fh,73h,67h,50h,6Dh,78h,1Ch,3Eh,1Dh,70h,6Eh,49h
终止

那么为什么我需要一个名为Aux的内存空间呢?谢谢你的回答。

当你减去

  movlw     'A'                 ;MOVE THE LETTER 'A' TO W REGISTER
  subwf     Character, W        ;REMANDEIR THE HEXADECIMAL VALUE OF 'P' AND 'A', 
。。。结果为负数,指向名为LetterTo7Segments的查找表之外

MPLAB IDE有很好的软件模拟器,可以用来检查代码

      subwf     Character, W        ;

这意味着从
文件
中减去
W
。但是您不能声明名为
字符的
文件
Character
是一个值为
'P'
的文本。您必须声明一个要使用的文件寄存器,就像您在第二个解决方案中所做的那样。

“Aux EQU 0x0D”只是为十六进制值0x0D指定了一个名称。它并没有在任何地方分配空间,我怀疑的是你对“LetterTo7Segments”的使用。在第一个代码中计算的值很可能远远超出跳转表的范围
      subwf     Character, W        ;