🚇

Subroutine and Stack

TypeQuiz 3 Material

Subroutine is another name for function

There is no “function” abstraction in LC-3 assembly. Need to create our own abstraction

JSR(Jump to Subroutine)

The JSR instruction computes the target address of the subroutine by sign-extending the 11-bit offset (bits [10:0]) of the instruction to 16 bits and adding that to the incremented PC.

Saves the PC value into R7 and then sets PC to the target1.

R7 = PC*(incremented)

PC = PC* + PCOffset11

PC-offset addressing (usually called with a label)

Note the order is important; we need to save the PC before changing it

JSRR(Jump to Subroutine, Register)

Same as JSR, but uses a register for the subroutine's address instead of a label/offset

R7 = PC*

PC = SR

RET(Return)

A special case of JMP. Equivalent to JMP R7

PC = R7

This is actually a “pseudo-instruction” since it assembles to the exact same bits as JMP R7

The Stack

Grows “downwards” towards smaller memory addresses from a fixed starting location

LAST IN FIRST OUT

How to call a subroutine

After subroutine returns

Frame Pointer

Calling Conventions

A caller is a function that calls another function; a callee is a function that was called. The currently-executing function is a callee, but not a caller.

Good read on caller/calleee: https://cs61.seas.harvard.edu/site/2018/Asm2/

If you only have one variable, subroutine will always be the same

If there are two or more, need to allocate more space

Building up the stack

Subroutine calling a subroutine

Questions

R5 - frame pointer

R6 - stack pointer

R7 - return address

Points to the first local variable on the stack. Exists to directly reference everything under it (stack frame up to that point is constant and never different. Everything after the frame pointer is dynamic and cant literally point to anything consistently.

DO NOT HAVE TO INITIALIZE R6

;subroutine template(2 args)

subroutine
	ADD R6, R6, -4
	STR R7, R6, 2
	STR R5, R6, 1
	ADD R5, R6, 0
	
	ADD R6, R6, -5
	STR R0, R5, -1
	STR R1, R5, -2
	STR R2, R5, -3
	STR R3, R5, -4
	STR R4, R5, -5


	;perform subroutine operation here

	;recursive call to subroutine.
	ADD R6, R6, -1 ; Push 1 on the stack
	STR RX, R6, 0 ; RX is the first arg to push
	ADD R6, R6, -1 ;Push 1 on the stack
	STR RX, R6, 0 ;RX is the second arg to push
	JSR subroutine ;Call subroutine
	LDR RX, R6, 0 ;Store return value to RX
	ADD R6, R6, 3 ;Pop the two pushed and the return value 
	STR RX, R5, 0 ;Store return value to local variable in current stack

	TEARDOWN
	  LDR R0, R5, 0     ;R0 = Local variable that holds the return value
	  STR R0, R5, 3     ;Retval = R0
	  LDR R4, R5, -5    ; Restore R4
	  LDR R3, R5, -4    ; Restore R3
	  LDR R2, R5, -3    ; Restore R2
	  LDR R1, R5, -2    ; Restore R0
	  LDR R0, R5, -1    ; Restore R1
	  ADD R6, R5, 0     ; Restore SP
	  LDR R5, R6, 1     ; Restore FP
	  LDR R7, R6, 2     ; Restore RA
	  ADD R6, R6, 3     ; Pop ra,fp,lv1

RET