Update example files

This commit is contained in:
Joscha 2019-11-10 18:17:32 +00:00
parent 957f65c380
commit 19aca3dfd1
5 changed files with 80 additions and 67 deletions

Binary file not shown.

Binary file not shown.

View file

@ -17,7 +17,7 @@ main:
STV counter STV counter
; Since we're top-level, we don't need to (re-)store our RA when calling ; Since we're top-level, we don't need to (re-)store our RA when calling
CALL sub-a CALL sub-1
; set counter bit 1 ; set counter bit 1
LDV counter LDV counter
@ -27,7 +27,7 @@ main:
HALT HALT
200: 200:
sub-a: sub-1:
; Set counter bit 2 ; Set counter bit 2
LDV counter LDV counter
ADC 0x04 ADC 0x04
@ -36,18 +36,18 @@ sub-a:
;; Store the current RA on the stack ;; Store the current RA on the stack
; Store the RA at current position of stack pointer ; Store the RA at current position of stack pointer
LDRA LDRA
STVR 0 STRS 0
; Move stack pointer by 1 since the stack grew ; Move stack pointer by 1 since the stack grew
LDSP LDSP
ADC -1 ADC -1
STSP STSP
; Call the subfunction ; Call the subfunction
CALL sub-b CALL sub-2
;; Pop and restore the RA from the stack ;; Pop and restore the RA from the stack
; Read RA from the top of the stack ; Read RA from the top of the stack
LDVR 1 LDRS 1
STRA STRA
; Remove top element from stack ; Remove top element from stack
LDSP LDSP
@ -62,7 +62,7 @@ sub-a:
RET RET
300: 300:
sub-b: sub-2:
; Set counter bit 4 ; Set counter bit 4
LDV counter LDV counter
ADC 0x10 ADC 0x10

Binary file not shown.

View file

@ -12,8 +12,7 @@
; Functions take a fixed number of arguments. For this example, all ; Functions take a fixed number of arguments. For this example, all
; values have a size of one word (24 bit). ; values have a size of one word (24 bit).
IAR = caller IAR = main
RA = 12345 ; to test whether the caller stores and restores the RA correctly
SP = 0xfffff SP = 0xfffff
FP = 0xfffff FP = 0xfffff
@ -29,78 +28,93 @@ tmp4: LIT 0
tmp5: LIT 0 tmp5: LIT 0
100: 100:
caller: main:
; 1. Push RA onto current stack frame CALL caller
LDRA HALT
STVR 0
LDSP
ADC -1
STSP ; SP offset: 1
; 2. Create a new shared stack frame 200:
caller:
;; 1. Initialisation
; 1.1. Create own stack frame
LDFP LDFP
STVR 0 STRS 0
LDSP LDSP
ADC -1 ADC -1
STSP STSP
STFP STFP
; 3. Push function parameters onto shared stack frame ; 2. Push RA onto current stack frame
LDC 5 LDRA
STVR 0 STRS 0
LDC 7
STVR -1
LDSP LDSP
ADC -2 ADC -1
STSP ; SP offset: 2 STSP
; 4. Create space for return values ; Do some work here
;; 2. Prepare call
; 2.1. Create a new shared stack frame
LDFP
STRS 0
LDSP LDSP
ADC -2 ADC -1
STSP; SP offset: 4 STSP
STFP
; 2.2. Write function parameters onto shared stack frame and keep
; space for return values
LDC 5
STRF 0
LDC 7
STRF -1
LDFP
ADC -4 ; 2 parameters and 2 return values
STSP
; Now, the shared stack frame looks like this: ; Now, the shared stack frame looks like this:
; 4: argument 1 ;
; 3: argument 2 ; FP offset | Value
; 2: return value 1 ; 0 | argument 1
; 1: return value 2 ; -1 | argument 2
; -2 | return value 1
; -3 | return value 2
; 5. Call callee ;; 3. Call callee
CALL callee CALL callee
; 6. Copy resulting values from the shared stack frame, so we can ;; 4. Cleanup after call
; 4.1. Copy resulting values from the shared stack frame, so we can
; restore our own stack frame ; restore our own stack frame
LDVR 2 LDRF -2
STV tmp1 STV tmp1
LDVR 1 LDRF -3
STV tmp2 STV tmp2
; 7. Restore own stack frame ; 4.2. Restore own stack frame
LDFP LDFP
ADC 1 ADC 1
STSP STSP
LDVR 0 LDRF 1
STFP STFP
; 8. Pop and restore RA ; Now, we can use the results stored in tmp1 and tmp2.
LDVR 1 ; Do some more work here
;; 5. Cleanup before RET
; 5.1. Pop and restore RA
LDRS 1
STRA STRA
LDSP LDSP
ADC 1 ADC 1
STSP ; SP offset: 0 STSP
; Now, we can use the results, or put them onto our own stack like so: RET
LDV tmp1
STVR 0
LDV tmp2
STVR -1
LDSP
ADC -2
STSP ; SP offset: 2
HALT 300:
500:
callee: callee:
; This callee doesn't really need its own stack since all ; This callee doesn't really need its own stack since all
; calculations did fit into the temporary variables. I still created ; calculations did fit into the temporary variables. I still created
@ -109,34 +123,33 @@ callee:
; 1. Create own stack frame ; 1. Create own stack frame
LDFP LDFP
STVR 0 STRS 0
LDSP LDSP
ADC -1 ADC -1
STSP STSP
STFP STFP
; Now, the shared stack frame looks like this: ; Since we've pushed the old FP to the shared stack frame (which now
; 5: argument 1 ; has length 5) and moved the FP to after that, we've in effect
; 4: argument 2 ; added 5 to the FP offset. This means that the shared stack frame
; 3: return value 1 ; now looks like this:
; 2: return value 2
; 1: previous FP
; ;
; The compiler needs to keep track of the offset of the SP within ; FP offset | Value
; the current stack frame, so that LDVR and STVR have the correct ; 5 | argument 1
; offset when accessing variables inside it (or the previous, shared ; 4 | argument 2
; stack frame). ; 3 | return value 1
; 2 | return value 2
; 2. Load arguments into temporary variables ; 2. Load arguments into temporary variables
LDVR 5 LDRF 5
STV tmp1 STV tmp1
LDVR 4 LDRF 4
STV tmp2 STV tmp2
; 3. Add arguments and put result into return value 1 ; 3. Add arguments and put result into return value 1
LDV tmp1 LDV tmp1
ADD tmp2 ADD tmp2
STVR 3 STRF 3
; 4. Multiply arguments and put result into return value 2 ; 4. Multiply arguments and put result into return value 2
LDC 0 LDC 0
@ -162,13 +175,13 @@ callee:
callee-loop-end: callee-loop-end:
; Save the result in return value 2 ; Save the result in return value 2
LDV tmp4 LDV tmp4
STVR 2 STRF 2
; 5. Restore shared stack frame ; 5. Restore shared stack frame
LDFP LDFP
ADC 1 ADC 1
STSP STSP
LDVR 0 LDRF 1
STFP STFP
; And this function is done :) ; And this function is done :)