OcR19
OcR19

Reputation: 23

8051 Assembly Language - Stack pointer initialization

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

Upvotes: 0

Views: 827

Answers (1)

the busybee
the busybee

Reputation: 12590

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.

Upvotes: 1

Related Questions