Developing Software in Assembly Language
Local Variables
By Jonathan W. Valvano

     This article, which discusses assembly language programming, accompanies the book Embedded Microcomputer Systems: Real Time Interfacing published by Brooks-Cole 1999. This document has four overall parts
     Overview
     Syntax (fields, pseudo ops)
     Local variables (this document)
     Examples

Local variables
      Introduction
      Memory Allocation of Local and Global Variables
      Implementation of Local Variables on the Stack
      Implementation of Local Variables using a Stack Frame
      C Compiler Implementation of Local and Global Variables
      Stack animation of a C function
      

 

Introduction to Local Variables
     Because their contents are allowed to change, all variables must be allocated in RAM and not ROM. A local variable is temporary information used only by one software module. Local variables are typically allocated, used, then deallocated. The information stored in a local variable is not permanent. This means if we store a value into a local variable during one execution of the module, the next time that module is executed the previous value is not available. Examples include loop counters, temporary sums. We use a local variable to store data that is temporary in nature. We can implement a local variable using the stack or registers. Reasons why we place local variables on the stack include
     dynamic allocation/release allows for reuse of memory
     limited scope of access provides for data protection
       only the program that created the local variable can access it
     since an interrupt will save registers and create its own stack frame, the code
       can be made reentrant.
     since absolute addressing is not used, the code is relocatable
     the number of variables is only limited by the size of the stack allocation
       that can be much larger than using local variables in registers

     A global variable is information shared by more than one program module. E.g., we use globals to pass data between the main (or foreground) process and an interrupt (or background) process. Global variables are not deallocated. The information they store is permanent. Examples include time of day, date, user name, temperature, pointers to shared data. On the 6811, we use absolute addressing (direct or extended) to access their information.

Observation: Sometimes we store temporary information in global variables out of laziness. This practice is to be discouraged because it wastes memory and may cause the module to not be reentrant.
     
--------------------------------------------------------------------------------------
Memory Allocation of Local and Global Variables
     
For more information on the allocation into specific type of memory within the embedded microcomputer see the section on Memory Allocation in Chapter 2 of Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano. On the Intel-based computers, global data, stack (hence local variables), and programs are divided into three separate memory segments. This division of code stack and data areas is an example of segmentation. Special segment registers point to each segment. Segmentation provides both speed and protection. A stack overflow can not destroy global data. In particular:
     Segment register DS points to the global data segment
     Segment register SS points to the stack segment
     Segment register CS points to the code segment

Segmentation is such a good idea that Apple implements it on the Macintosh, even though the 68000 provides for no hardware support of segmentation
     A5 relative addressing is used to access global data
     SP points to the stack and local variables
     PC points to the current instruction.

     Because the embedded system does not load programs off disk when started, segmentation is an extremely important issue for these systems as well. Typical software segments include global variables, local variables, fixed constants, and machine instructions. For single chip implementations, recall that there are three types of memory:

Memory volatile? Ability to Read/Write
RAM  volatile random and fast access
EEPROM nonvolatile easily erased and reprogrammed
ROM nonvolatile programmed once

In an embedded application, we usually put structures that must be changed during execution in RAM. Examples include recorded data, parameters passed to subroutines, global and local variables. We place fixed constants in EEPROM because the information remains when the power is removed, but can be reprogrammed at a later time. Examples of fixed constants include translation tables, security codes, calibration data, and configuration parameters. We place machine instructions, interrupt vectors (address to go to when an interrupt occurs) and the reset vector (starting address) in ROM because this information is stored once and can not be reprogrammed. Because the machine instructions and vectors are in ROM, the software will begin execution when power is applied.

--------------------------------------------------------------------------------------
Implementation of Local Variables on the Stack
     
Stack implementation of local variables has four stages: binding, allocation, access, and deallocation.

1. Binding is the assignment of the address (not value) to a symbolic name. This address will be the actual memory location to store the local variable. The assembler binds the Symbolic name to a stack index. The computer calculates the actual location during execution. For example:

; MC68HC708XL36
I       set  1  8 bit number
PT      set  2  16 bit address
Result  set  4  8 bit number

; MC68HC11A8 or MC68HC812A4
I       set  0  8 bit number
PT      set  1  16 bit address
Result  set  3  8 bit number

2. Allocation is the generation of memory storage for the local variable. The computer allocates space during execution by decrementing the SP. In this first example, the software allocates the local variable by pushing a register on the stack.

; MC68HC708XL36
     
psha    allocate Result
     
pshx    allocate PT (lsbyte)
     
pshh     (msbyte)
     
psha    allocate I

; MC68HC11A8 or MC68HC812A4
     
psha    allocate Result
     
pshx    allocate PT
     
psha    allocate I

In this next example, the software allocates the local variable by decrementing the stack pointer.

; MC68HC11A8 or MC68HC812A4
     
des    allocate Result
     
des    allocate PT
     
des
     
des    allocate I

In this last example, the technique provides a mechanism for allocating large amounts of stack space.

; MC68HC708XL36
     
ais  #-4  alloc Result, PT, I

; MC68HC11A8
     
tsx    allocate I,PT,Result
     
xgdx
     subd  
#4
     xgdx
     txs

; MC68HC812A4
     
leas  -4,sp  alloc Result, PT, I

3. The access to a local variable is a read or write during execution. In the next program, the local variable Iis cleared, the local variable PT is copied into a register, and the local variable Result is written.
; MC68HC708XL36
     
clr  I,sp  Clear I
     
ldx  PT,sp  msbyte
     
pshx
     
pulh    H is msbyte of PT
     
ldx  PT+1,sp  lsbyte
     
sta  Result,sp  store Result

; MC68HC11A8
     
tsx    Reg X points to locals
     
clr  I,x  Clear I
     
ldy  PT,x  Reg Y is a copy of PT
     
staa Result,x  store into Result

; MC68HC812A4
     
clr  I,sp  Clear I
     
ldy  PT,sp  Reg Y is a copy of PT
     
staa Result,sp  store into Result

4. Deallocation is the release of memory storage for the location variable. The computer deallocates space during execution by incrementing SP. In this first example, the software deallocates the local variable by pulling a register from the stack.

; MC68HC708XL36
     
pula    deallocate Result
     
pulx    deallocate PT (lsbyte)
     
pulh     (msbyte)
     
pula    deallocate I

; MC68HC11A8 or MC68HC812A4
     
pula    deallocate Result
     
pulx    deallocate PT
     
pula    deallocate I


Observation: When the software uses the "push-register" technique to allocate and the "pull-register" technique to deallocate, it looks like it is saving and restoring the register. Because most applications of local variables involve storing into the local, the value pulled will NOT match the value pushed.
     

In this next example, the software deallocates the local variable by incrementing the stack pointer.
; MC68HC11A8 or MC68HC812A4
     
ins    deallocate Result
     
ins    deallocate PT
     
ins
     
ins    deallocate I

In this last example, the technique provides a mechanism for allocating large amounts of stack space.

; MC68HC708XL36
     
ais  #4  dealloc Result, PT, I

; MC68HC11A8
     
tsx    deallocate I,PT,Result
     
ldab  #4
     
abx
     
txs

; MC68HC812A4
     
leas  4,sp  deallocate Result,PT,I

Implementation of Local Variables using a Stack Frame
     
The 6812 provides a negative offset index addressing mode. With this addressing mode it is possible to establish a stack frame pointer using either register X or Y. It is important in this implementation that once the stack frame pointer is established (e.g., the tsx instruction), that the stack frame register (X) not be modified. Because the stack frame pointer should not be modified, every subroutine will save the old stack frame pointer of the function that called the subroutine (e.g., pshx at the top) and restore it before returning (e.g., pulx at the bottom.) The tsx instruction will create the stack frame, the leas -4,sp will allocate 4 bytes of local storage and the txs will deallocate the local variables. Local variable access uses indexed addressing mode with a negative offset. This example will be extended to include parameters later in the chapter. In particular, the ICC12 C compiler uses this method to access local variables and stack. Notice the subroutine deallocated by moving the stack frame pointer back into SP with the txs instruction.
; MC68HC812A4
; *****binding phase***************
I    set  -4
PT   set  -3
Ans  set  -1
; *******allocation phase *********
function  pshx    save old Reg X
     
tsx          create stack frame pointer
     
leas  -4,sp  allocate four bytes for I,PT,Result
; ********access phase ************
     
clr  I,x    Clear I
     
ldy  PT,x   Reg Y is a copy of PT
     
staa Ans,x  store into Ans
; ********deallocation phase *****
     
txs  deallocation
     
pulx  restore old X
     
rts

Observation: One advantage of the stack frame method is the ability to push and pull data from the stack within the function without changing Reg X. In this way, the binding of the local variables remains fixed.
     

--------------------------------------------------------------------------------------
Application of Local Variables
     
Although on most systems local variables are implemented on the stack, we have adopted a more general definition of local variables in this book. Recall, that a local variable is temporary storage accessed by only one module. In order to compare and contract various implementations of local variables, consider a few subroutines that implement 8 bit signed multiply. On the 6805 and 6808 we will multiply register A and X and return the 16 bit result in the register combination X:A. On the 6811 and 6812 we will multiple registers A times B and return the 16 bit result in register D. In each case there is a local variable, SIGN, which when true (nonzero), means the result will be negative. In the first example, the local variable is allocated in global memory and accessed using direct or extended addressing. This technique is simple and easy to debug, but is not relocatable or reentrant. On the other hand, it is the only available method for the 6805. Notice that the allocation occurs at assembly time, and is fixed. In other words it is never allocated, and not reused.
The following is a 6805 implementation of local variables using direct addressing.
; MC68HC705J1A
     
 org  $0000  RAM
SIGN  rmb  1      Allocation
     
 org  $0300  EPROM
SMUL  clr  SIGN   direct addr
     
 tsta        Is A negative?
     
 bpl  APOS   Skip if positive
     
 com  SIGN   Flip sign
     
 nega        0 <= A <= 128
APOS  tstx        Is X negative?
     
 bpl  XPOS   Skip if positive
     
 com  SIGN   Flip sign
     negx        0 <= X <= 128
XPOS  mul         Unsigned AX
    
  tst  SIGN   negate result?
    
  beq  POS    Skip if positive
   
   coma        1's complement
   
   comx
      
add  #1     plus one
  
    bcc  POS
   
   incx        carry
POS   rts         Never dealloc

The following is a 6808 implementation of local variables using direct addressing.
; MC68HC708XL36
     
 org  $0050  RAM
SIGN  rmb  1      Allocation
     
 org  $6E00  EEPROM
SMUL  clr  SIGN   direct addr
     
 tsta        Is A negative?
    
  bpl  APOS   Skip if positive
     
 com  SIGN   Flip sign
     
 nega        0 <= A <= 128
APOS  tstx        Is X negative?
    
  bpl  XPOS   Skip if positive
   
   com  SIGN   Flip sign
      negx        0 <= X <= 128
XPOS  mul         Unsigned AX
    
  tst  SIGN   negate result?
    
  beq  POS    Skip if positive
   
   coma    1's complement
  
    comx
      
add  #1  plus one
   
   bcc  POS
    
  incx    carry
POS   rts    Never dealloc

The following is a 6811 implementation of local variables using direct addressing.
; MC68HC11A8
     
org  0     RAM
SIGN rmb  1     Allocation of local
     
org  $E000 ROM
SMUL clr  SIGN  direct addressing
     
tsta       Is A negative?
     
bpl  APOS  Skip if A positive
     
com  SIGN  Flip sign
     
nega       0 <= A <= 128
APOS tstb       Is B negative?
     
bpl  BPOS  Skip if B positive
     
com  SIGN  Flip sign
     
negb       0 <= B <= 128
BPOS mul        Unsigned AB
     
tst  SIGN  Need to negate D?
     
beq  DPOS  Skip if positive
     
coma       1's complement
     
comb
     
addd  #1   plus one
DPOS  rts       Never deallocated

The following is a 6812 implementation of local variables using extended addressing.
; MC68HC812A4
     
org  $0800 RAM
SIGN rmb  1     Allocation of local
     
org  $F000 EEPROM
SMUL clr  SIGN  extended addressing
     
tsta       Is A negative?
     
bpl  APOS  Skip if A positive
     
com  SIGN  Flip sign
     
nega       0 <= A <= 128
APOS tstb       Is B negative?
     
bpl  BPOS  Skip if B positive
     
com  SIGN  Flip sign
     
negb       0 <= B <= 128
BPOS mul        Unsigned AB
     
tst  SIGN  Need to negate D?
     
beq  DPOS  Skip if positive
     
coma       1's complement
     
comb
     
addd  #1   plus one
DPOS rts        Never deallocated

In the second example, the local variable is implemented using a register. This technique is simple and very fast. It is appropriate for small amounts of data. Because no absolute memory addresses are required to access the registers, the subroutine will be reentrant. If the function saves and restores registers it will be reentrant. All of the Motorola 8 bit microcomputers have very few registers, so this technique will have limited application. There is no formal allocation or deallocation of the register, but the register can certainly be reused after the information is no longer needed. A 6805 implementation is not given because it doesn’t have enough registers.

6808 implementation of local variables using registers.
; MC68HC708XL36
SMUL clrh       H=sign
     
tsta       Is A negative?
     
bpl  APOS  Skip if positive
     
aix  #$60  set H=1
     
aix  #$60
     
aix  #$40
     
nega       0 <= A <= 128
APOS tstx       Is X negative?
     
bpl  XPOS  Skip if positive
     
aix  #$80  H=H-1
     
aix  #$80  Flip sign
     
negx       0 <= X <= 128
XPOS  mul       Unsigned AX
     
psha
     
pshh
     
pula
     
tsta     negate result?
     
pula
     
beq  POS Skip if positive
     
coma     1's complement
     
comx
     
add  #1  plus one
     
bcc  POS
     
incx     carry
POS  rts      Never dealloc

6811/6812 implementation of local variables using registers.
; MC68HC11A8 or MC68HC812A4
     
org  $E000  ROM
SMUL ldy  #0     Y=sign
     
tsta        Is A negative?
     
bpl  APOS   Skip if A positive
     
iny         Flip sign
     
nega        0 <= A <= 128
APOS tstb        Is B negative?
     
bpl  BPOS   Skip if B positive
     
dey         Flip sign
     
negb        0 <= B <= 128
BPOS mul         Unsigned AB
     
cpy  #0     Need to negate D?
     
beq  DPOS   Skip if positive
     
coma        1's complement
     
comb
     
addd  #1    plus one
DPOS rts         Never deallocated

     In the last example, the local variable is allocated on the stack and accessed using indexed addressing. Allocation occurs dynamically (i.e., at run time). The deallocation step allows the memory to be reused for other purposes. Because the 6805 does not have stack relative addressing, a 6805 implementation is not shown. Because a new "private" copy is allocated when the subroutine is entered, the subroutine is re-entrant. The indexed addressing mode does not depend on the PC, so the subroutine is also relocatable.

6808 implementation of local variables using index addressing
; MC68HC708XL36
SIGN  equ  1        binding
SMUL  ais  #-1      allocation
     
 clr  SIGN,SP  Stack access
     
 tsta          Is A negative?
     
 bpl  APOS     Skip if positive
     
 com  SIGN,SP  Flip sign
     
 nega          0 <= A <= 128
APOS  tstx          Is X negative?
    
  bpl  XPOS     Skip if positive
     
 com  SIGN,SP  Flip sign
     
 negx          0 <= X <= 128
XPOS  mul           Unsigned A*X
    
  tst  SIGN,SP  negate?
     
 beq  POS      Skip if OK
     
 coma          1's complement
    
  comx
      
add  #1       plus one
     
 bcc  POS
     
 incx          carry
POS   ais  #1       deallocation
     
 rts

6811/6812 implementation of local variables using index addressing
; MC68HC11A8 or MC68HC812A4
SIGN equ  0       binding
SMUL des          allocation
     
tsx          X -> SIGN
     
clr  SIGN,X  Stack access
     
tsta         Is A negative?
     
bpl  APOS    Skip if positive
     
com  SIGN,X  Flip sign
     
nega         0 <= A <= 128
APOS tstb         Is B negative?
     
bpl  BPOS    Skip if positive
     
com  SIGN,X  Flip sign
     
negb         0 <= B <= 128
BPOS mul          Unsigned A*B
     
tst  SIGN,X  Need to negate?
     
beq  DPOS    Skip if OK
     
coma         1's complement
     
comb
     
addd  #1     plus one
DPOS ins          deallocation
     
rts
     
6812 implementation of local variables using SP index addressing
; MC68HC812A4
SIGN equ  0        binding
SMUL des           allocation
     
clr  SIGN,SP  Stack access
     
tsta          Is A negative?
     
bpl  APOS     Skip if positive
     
com  SIGN,SP  Flip sign
     
nega          0 <= A <= 128
APOS tstb          Is B negative?
     
bpl  BPOS     Skip if positive
     
com  SIGN,SP  Flip sign
     
negb          0 <= B <= 128
BPOS mul           Unsigned AB
     
tst  SIGN,SP  Need to negate?
     
beq  DPOS     Skip if OK
     
coma          1's complement
     
comb
     
addd  #1      plus one
DPOS ins           deallocation
     
rts

In the above example, the line SIGN equ 0 is an assembly-time pseudo-instruction used only to make the source code more readable. Unfortunately with most assemblers, the label can only be defined once with an equ. Thus, we can not reuse local variable names. Some assemblers, like TExaS, provide the set pseudo-instruction, which works like equ, but allows you to redefine its value. Thus using set, you can reuse a local variable name.

--------------------------------------------------------------------------------------
C Compiler Implementation of Local and Global Variables
    
In order to understand both the machine architecture and the C compiler, we can look at the assembly code generated. This first example shows a simple C program with a global variable x, two local variables both called yand a function parameter z.
int x;    /* definition of a global variable */
main(){
     int y;  /* definition of a local variable */
     x=5;  
  /* access global variable */
     y=6;  
  /* access local variable */
     x=sub(y);  /* call function, pass parameter */
     return(0);}

int sub(int z){ int y;
     y=z+1;
     return(y);}

The first compiler we will study is Symantec Think C version 7 for the 68K Macintosh. The disassembled output has been edited to clarify its operation. The loader will allocate 3 segmented memory areas: code pointed to by the PC; global pointed to by A5; and local pointed to by the stack pointer A7. The global symbol, x, will be assigned or bound by the loader. "Binding" means establishing its address. The compiler can bind the local variables and subroutine parameters. The link instruction establishes a stack frame pointer, A6, and allocates local variables. The actual ThinkC compiler optimized the subroutine by placing the local variable, y, in register D7, but in this example, I "unoptimized" it to illustrate the use of local variables.
     

y equ -2 local variable binding A6 relative
main: LINK A6,#-2 allocate y for main
  MOVE.W #5,x(A5) x=5;
  MOVE.W #6,y(A6) y=6;
  MOVE.W y(A6),-(A7) call by value
  JSR sub  
  MOVE.W D0,x(A5) x=result of sub
  MOVEQ #0,D0  
  UNLK A6  
  RTS    
       
y equ -2 local variable binding A6 relative
z equ 8 Parameter binding A6 relative
sub: LINK A6,#-2 allocate y for sub
  MOVEQ.W #1,y(A6)  
  ADD.W z(A6),y(A6) y=z+1;
  MOVE.W y(A6),D0 D0 is the return parameter
  UNLK A6 deallocate y
  RTS    

The stack frame at the time of the ADD.W z(A6),y(A6) instruction is shown. Within the subroutine the local variables of main are not accessible.

The next compiler we will study is ImageCraft ICC11 version 4.0 for the Motorola 6811. Again, the disassembled output has been edited to clarify its operation. The linker/loader also allocates 3 segmented memory areas: code pointed to by the PC; global accessed with absolute addressing; and locals pointed to by the stack pointer SP. The global symbol, _x, will be assigned or bound by the linker/loader. The pshx instruction allocates the local variable, and the TSX instruction establishes a stack frame pointer, X. This compiler passes the first input parameter into the subroutine by placing it in register D. The remaining parameters (none in this example) would have been pushed on the stack..
     

y equ 0 local variable binding X relative
main: PSHX   allocate y for main
  TSX   establish stack frame pointer
  LDD #5  
  STD _x x=5;
  LDD #6  
  STD y,X y=6;
  JSR sub  
  STD _x x=result of sub
  CLRA    
  CLRB    
  PULX   deallocate y
  RTS    
       
y equ 0 local variable binding X relative
z equ 2 Parameter binding X relative
sub: PSHB   put parameter on stack
  PSHA    
  PSHX   allocate y for sub
  TSX   establish stack frame pointer
  LDD z,X  
  ADDD #1  
  STD y,X y=z+1;
  PULX   deallocate y
  PULX   discard z
  RTS   RegD is the return parameter

The stack frame at the time of the ADDD #1 instruction is shown. Within the subroutine the local variables of main are not accessible.

The third compiler we will study is ImageCraft ICC12 version 4.0 for the Motorola 6812. Again, the disassembled output has been edited to clarify its operation. Like the 6811, the linker/loader also allocates 3 segmented memory areas: code pointed to by the PC; global accessed with absolute addressing; and locals pointed to by the stack pointer SP. The leas -2,sp instruction allocates the local variable, and the tfr s,x instruction establishes a stack frame pointer, X. ImageCraft ICC12 compiler passes the first input parameter into the subroutine by placing it in register D. The remaining parameters (none in this example) would have been pushed on the stack..
     

y equ -2 ;local variable binding X relative
main: pshx   ; main()
  tfr s,x ; X is the stack frame pointer
  leas -2,sp ; allocate y int y;
  movw #5,_x ; x=5;
  movw #6,-2,x ; y=6;
       
  ldd -2,x ; parameter in RegD
  jsr sub ; x=sub(y);
  std _x ; store return in global x
  ldd #0 ; return(0);}
  tfr x,s  
  pulx    
  rts    
Y equ -4 ; local variable binding X relative
Z equ -2 ; Parameter binding X relative
sub: pshx   ; int sub(int z){
  tfr s,x  
  pshd    
  leas -2,sp ; allocate y int y;
  ldd Z,x ; y=z+1;
  addd #1  
  std Y,x  
  ldd Y,x ; return(y);}
  tfr x,s  
  pulx    
  rts    


The stack frame at the time of the ADDD #1 instruction is shown. Within the subroutine the local variables of main are not accessible.

The fourth compiler we will study is Borland C version 3 for the Intel 386 IBM-PC. The disassembled output has been edited to clarify its operation. The small memory model was used. With the large memory models, the short call would be replaced with a far callf. Similar to the Macintosh, the loader will allocate 3 segmented memory areas: code pointed to by the CC:IP; global accessed with data segment addressing DS:offset; and local pointed to by the stack pointer SP. The offset of global symbol, x, can be bound by the compiler. The loader will establish the position in memory and set the segment register, DS. The compiler can bind the local variables and subroutine parameters. The SUB SP,2 instruction allocates the local variable, and the PUSH BP MOV BP,SP instructions establishes a stack frame pointer, SS:BP. In later versions of the compiler, these three instructions are replaced by the single instruction ENTER. The MOV SP,BP POP BP instructions are replaced by LEAVE.
     

ymain: PUSH BP  
  MOV BP,SP establish stack frame
  SUB SP,2 allocate y for main
  MOV word ptr[x],5 x=5;
  MOV word ptr[BP+y],6 y=6;
  PUSH word ptr[BP+y] call by value
  CALL sub  
  POP CX discard parameter
  MOV [x],AX x=result of sub
  XOR AX,AX  
  MOV SP,BP  
  POP BP  
  RET    
       
y equ -2 local binding BP relative
z equ 4 Parameter binding BP relative
sub: PUSH BP  
  MOV BP,SP establish stack frame
  SUB SP,2 allocate y for sub
  MOV AX,[BP+z]  
  INC AX  
  MOV [BP+y],AX y=z+1;
  MOV AX,[BP+y] AX is the return parameter
  MOV SP,BP  
  POP BP  
  RET    

 

The stack frame at the time of the INC AX instruction is shown. Within the subroutine the local variables of main are not accessible.

 

--------------------------------------------------------------------------------------
Stack animation of a C function

In order to understand both the machine architecture and the C compiler, we can look at the assembly code generated. This example shows a simple C program with three local variables. Although the function doesn't do much it will serve to illustrate how local variables are created (allocation), accessed (read and write) and destroyed (deallocated.)

void sub(void){ short y1,y2,y3;   /* 3 local variables*/
    y1=1000;
    y2=2000;
    y3=y1+y2;
}

The compiler we will study is the ImageCraft ICC12 version 5.0 for the Motorola 6812. The disassembled output has been edited to clarify its operation (although the compiler does create the "; y3 -> -6,x" comment). The linker/loader allocates 3 segmented memory areas: code pointed to by the PC; global accessed with absolute addressing; and locals pointed to by the stack pointer SP. The leas -6,sp instruction allocates the local variables, and the tfr s,x instruction establishes a stack frame pointer, X. Within the subroutine the local variables of other functions are not accessible.

 

 

 

 This document has four overall parts
     Overview
     Syntax (fields, pseudo ops)
     Local variables (this document)
     Examples