[英]8051 Assembly Language - Stack pointer initialization
考虑到 8051 微型 controller RAM 组织,我想将堆栈指针设置为地址 30h。
我想知道我是否必须在我的程序开始时只做一次,或者是否有必要在 if 语句的 2 个分支中的每个子例程调用之前设置它? 子程序结束后堆栈是否重置为 7fh? 还是会在整个程序执行期间保持设置为 30h? 我的代码如下:
$ NOMOD51
$ INCLUDE (reg517.inc)
ORG 0H
MOV R1, #90H ;load register 1 with address 90h
MOV @R1, #00H ;initialize adress 90h indirectly, via register 1
MOV A, #00H
;MOV SP, 30H ; should this instruction go here???
FORLOOP:
INC A ;increment register 1 by 1
MOV @R1,A ;load the accumulator with the content of 90h indirectly addressed via R1
CJNE @R1, #3d, IFSTATEMENT ;if aacumulator contents not 11, jump to condition
JMP ENDLABEL ;else jump to end label
IFSTATEMENT:
JNB 23h, SETBIT ;condtion: if bit 23h is not set, jump to set bit instruction
JMP CLEARBIT ;else jump to clear bit instruction
SETBIT:
SETB 23H ;set memory bit 23h
MOV P0, #0FFH ;load all bits of port 0
MOV SP, 30H ;set stack pointer to scratch pad area, since we are about to call a subroutine
;MOV SP, 30H ; or here???
LCALL DELAY ;call the Delay subroutine
JMP FORLOOP ;after 3s jump back to the for loop
CLEARBIT:
CLR 23h ;set memory bit 23h
MOV P0, #00H ;clear all bits of port 0
;MOV SP, 30H ; or here???
LCALL DELAY ;call the Delay subroutine
JMP FORLOOP ;after 3s jump back to the for loop
DELAY: ;delay of 250 x 250 x 24 instruction cycles = 3000000ums = 3s
MOV R3, #1d
L3:
MOV R2, #1d
L2:
MOV R1, #1d
L1:
DJNZ R1, L1
DJNZ R2, L2
DJNZ R3, L3
RET
ENDLABEL:
END
请查阅任何关于 8051 的好书,您会发现:
SP
只需在初始化部分设置一次,并且仅在您对其初始值不满意时才需要设置。xCALL
和RET
会自动增加和减少SP
,并且仅在必要时进行。 你最好别惹它。SP
的其他常见指令是PUSH
和POP
。 您需要使它们保持平衡,直到您确切知道自己在做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.