0

Considering the 8051 micro controller RAM organization, I would like to set my stack pointer to address 30h.

I would like to know if I have to do it only once in the beginning of my program, or is it necessary to set it before every subroutine call in the 2 branches of the if statement? Is the stack reset to 7fh after a subroutine ends? Or would it stay set to 30h during the whole program execution? My code is as follows:

$ 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
OcR19
  • 23
  • 4
  • 2
    You only need to set it once, then keep it balanced. – Jester Jan 24 '22 at 13:43
  • 1
    You are use wrong instruction to setup SP register. This move content of the memory address 30h to SP. This content is unpredicted after power up. You should use instruction MOV SP,#30h. This move constant 30h to SP register – Peter Plesník Jan 24 '22 at 17:05

1 Answers1

1

Please consult any decent book on 8051, and you will find:

  • The SFR SP needs to be set only once in the initializing part, and only if you are not happy with its initial value.
  • xCALL and RET increment and decrement the SP automatically, and only as necessary. You better not mess with it.
  • Other common instructions that change the SP are PUSH and POP. You need to keep them balanced, until you exactly know what you are doing.
the busybee
  • 10,755
  • 3
  • 13
  • 30
  • Thanks lot! Yeah I'll be sure to do that, I'm currently only using the material provided by my university and they are not that specific. – OcR19 Jan 24 '22 at 15:38
  • 1
    You could start by asking your favorite web search engine, there are lots of user's manuals and tutorials. Anyway, if you think this post answers your question, please mark it as such after some time. – the busybee Jan 24 '22 at 16:08