0

I'm having trouble getting this source code to compile. Could you guys please tell me where I'm going wrong? The source code is compiled in LC3EDIT and then ran in LC3simulator. Here is the source code and routines. I've changed everything that's suppose to be changed and the labels, etc. What's going on here?

Thanks,
Matt
When I try and compile this, I get the following errors,
Line94: Unrecognized opcode or syntax error at or before 'BRznp'

Line94: Unrecognized opcode or syntax error at or before 'newCommand'

Line101: Unrecognized opcode or syntax error at or before 'ASCIItoBinary'

Here is a link to the compiler and simulator:

simulator: http://highered.mcgraw-hill.com/sites/0072467509/student_view0/lc-3_simulator.html
compiler:http://highered.mcgraw-hill.com/sites/0072467509/student_view0/c_to_lc-3_compiler.html

;
; Routine to pop the top two elements from the stack,
; add them, and push the sum onto the stack. R6 is
; the stack pointer.
;
.ORIG x3000
OpAdd JSR POP ; Get first source operand.
ADD R5,R5,#0 ; Test if POP was successful.
BRp Exit ; Branch if not successful.
ADD R1,R0,#0 ; Make room for second operand
JSR POP ; Get second source operand.
ADD R5,R5,#0 ; Test if POP was successful.
BRp Restore1 ; Not successful, put back first.
ADD R0,R0,R1 ; THE Add.
JSR RangeCheck ; Check size of result.
BRp Restore2 ; Out of range, restore both.
JSR PUSH ; Push sum on the stack.
RET ; On to the next task...
Restore2 ADD R6,R6,#-1 ; Decrement stack pointer.
Restore1 ADD R6,R6,#-1 ; Decrement stack pointer.
Exit BRnzp NewCommand
;
; Routine to check that the magnitude of a value is
; between -999 and +999.
;
RangeCheck LD R5,Neg999
ADD R4,R0,R5 ; Recall that R0 contains the
BRp BadRange ; result being checked.
LD R5,Pos999
ADD R4,R0,R5
BRn BadRange
AND R5,R5,#0 ; R5 <-- success
RET
BadRange ST R7,Save ; R7 is needed by TRAP/RET
LEA R0,RangeErrorMsg
TRAP x22 ; Output character string
LD R7,Save
AND R5,R5,#0 ;
ADD R5,R5,#1 ; R5 <-- failure
RET
Neg999 .FILL #-999
Pos999 .FILL #999
Save .FILL x0000
RangeErrorMsg .FILL x000A
.STRINGZ "Error: Number is out of range."
;
; Algorithm to pop two values from the stack, multiply them
; and if their product is within the acceptable range, push
; the result on the stack. R6 is stack pointer.
;
OpMult AND R3,R3,#0 ; R3 holds sign of multiplier.
JSR POP ; Get first source from stack.
ADD R5,R5,#0 ; Test for successful POP
BRp Exit ; Failure
ADD R1,R0,#0 ; Make room for next POP
JSR POP ; Get second source operand
ADD R5,R5,#0 ; Test for successful POP
BRp Restore1 ; Failure; restore first POP
ADD R2,R0,#0 ; Moves multiplier, tests sign
BRzp PosMultiplier
ADD R3,R3,#1 ; Sets FLAG: Multiplier is neg
NOT R2,R2
ADD R2,R2,#1 ; R2 contains -(multiplier)
PosMultiplier AND R0,R0,#0 ; Clear product register
ADD R2,R2,#0
BRz PushMult ; Multiplier = 0, Done.
;
MultLoop ADD R0,R0,R1 ; THE actual "multiply"
ADD R2,R2,#-1 ; Iteration Control
BRp MultLoop
;
JSR RangeCheck
ADD R5,R5,#0 ; R5 contains success/failure
BRp Restore2
;
ADD R3,R3,#0 ; Test for negative multiplier
BRz PushMult
NOT R0,R0 ; Adjust for
ADD R0,R0,#1 ; sign of result
PushMult JSR PUSH ; Push product on the stack.
RET
Restore4 ADD R6,R6,#-1 ; Adjust stack pointer.
Restore3 ADD R6,R6,#-1 ; Adjust stack pointer.
Exit7 BRnzp NewCommand
; Algorithm to pop the top of the stack, form its negative,
; and push the result on the stack.
;
OpNeg JSR POP ; Get the source operand
ADD R5,R5,#0 ; test for successful pop
BRp Exit ; Branch if failure
NOT R0,R0
ADD R0,R0,#1 ; Form the negative of the source.
JSR PUSH ; Push the result on the stack.
Exit3 BRznp NewCommand
;
; This algorithm takes an ASCII string of three decimal digits and
; converts it into a binary number. R0 is used to collect the result.
; R1 keeps track of how many digits are left to process. ASCIIBUFF
; contains the most significant digit in the ASCII string.
;
ASCIItoBinary AND R0,R0,#0 ; R0 will be used for our result
ADD R1,R1,#0 ; Test number of digits.
BRz DoneAtoB ; There are no digits
;
LD R3,NegASCIIOffset ; R3 gets xFFD0, i.e., -x0030
LEA R2,ASCIIBUFF
ADD R2,R2,R1
ADD R2,R2,#-1 ; R2 now points to "ones" digit
;
LDR R4,R2,#0 ; R4 <-- "ones" digit
ADD R4,R4,R3 ; Strip off the ASCII template
ADD R0,R0,R4 ; Add ones contribution
;
ADD R1,R1,#-1
BRz DoneAtoB ; The original number had one digit
ADD R2,R2,#-1 ; R2 now points to "tens" digit
;
LDR R4,R2,#0 ; R4 <-- "tens" digit
ADD R4,R4,R3 ; Strip off ASCII template
LEA R5,LookUp10 ; LookUp10 is BASE of tens values
ADD R5,R5,R4 ; R5 points to the right tens value
LDR R4,R5,#0
ADD R0,R0,R4 ; Add tens contribution to total
;
ADD R1,R1,#-1
BRz DoneAtoB ; The original number had two digits
ADD R2,R2,#-1 ; R2 now points to "hundreds" digit
;
LDR R4,R2,#0 ; R4 <-- "hundreds" digit
ADD R4,R4,R3 ; Strip off ASCII template
LEA R5,LookUp100 ; LookUp100 is hundreds BASE
ADD R5,R5,R4 ; R5 points to hundreds value
LDR R4,R5,#0
ADD R0,R0,R4 ; Add hundreds contribution to total
;
DoneAtoB RET
NegASCIIOffset .FILL xFFD0
ASCIIBUFF .BLKW 4
LookUp10 .FILL #0
.FILL #10
.FILL #20
.FILL #30
.FILL #40
.FILL #50
.FILL #60
.FILL #70
.FILL #80
.FILL #90
;
LookUp100 .FILL #0
.FILL #100
.FILL #200
.FILL #300
.FILL #400
.FILL #500
.FILL #600
.FILL #700
.FILL #800
.FILL #900
;
; This algorithm takes the 2's complement representation of a signed
; integer, within the range -999 to +999, and converts it into an ASCII
; string consisting of a sign digit, followed by three decimal digits.
; R0 contains the initial value being converted.
;
BinarytoASCII LEA R1,ASCIIBUFF ; R1 points to string being generated
ADD R0,R0,#0 ; R0 contains the binary value
BRn NegSign ;
LD R2,ASCIIplus ; First store the ASCII plus sign
STR R2,R1,#0
BRnzp Begin100
NegSign LD R2,ASCIIminus ; First store ASCII minus sign
STR R2,R1,#0
NOT R0,R0 ; Convert the number to absolute
ADD R0,R0,#1 ; value; it is easier to work with.
;
Begin100 LD R2,ASCIIoffset ; Prepare for "hundreds" digit
;
LD R3,Neg100 ; Determine the hundreds digit
Loop100 ADD R0,R0,R3
BRn End100
ADD R2,R2,#1
BRnzp Loop100
;
End100 STR R2,R1,#1 ; Store ASCII code for hundreds digit
LD R3,Pos100
ADD R0,R0,R3 ; Correct R0 for one-too-many subtracts
;
LD R2,ASCIIoffset ; Prepare for "tens" digit
;
Begin10 LD R3,Neg10 ; Determine the tens digit
Loop10 ADD R0,R0,R3
BRn End10
ADD R2,R2,#1
BRnzp Loop10
;
End10 STR R2,R1,#2 ; Store ASCII code for tens digit
ADD R0,R0,#10 ; Correct R0 for one-too-many subtracts
Begin1 LD R2,ASCIIoffset ; Prepare for "ones" digit
ADD R2,R2,R0
STR R2,R1,#3
RET
;
ASCIIplus .FILL x002B
ASCIIminus .FILL x002D
ASCIIoffset .FILL x0030
Neg100 .FILL xFF9C
Pos100 .FILL x0064
Neg10 .FILL xFFF6
;
; The Calculator, Main Algorithm
;
LEA R6,StackBase ; Initialize the Stack.
ADD R6,R6,#1 ; R6 is stack pointer
LEA R0,PromptMsg
PUTS
GETC
OUT
;
; Check the command
;
Test LD R1,NegX ; Check for X
ADD R1,R1,R0
BRz Exit
;
LD R1,NegC ; Check for C
ADD R1,R1,R0
BRz OpClear ; See Figure 10.27
;
LD R1,NegPlus ; Check for +
ADD R1,R1,R0
BRz OpAdd ; See Figure 10.10
;
LD R1,NegMult ; Check for *
ADD R1,R1,R0
BRz OpMult ; See Figure 10.14
;
LD R1,NegMinus ; Check for -
ADD R1,R1,R0
BRz OpNeg ; See Figure 10.15
;
LD R1,NegD ; Check for D
ADD R1,R1,R0
BRz OpDisplay ; See Figure 10.26
;
; Then we must be entering an integer
;
BRnzp PushValue ; See Figure 10.23
;
NewCommand1 LEA R0,PromptMsg
PUTS
GETC
OUT
BRnzp Test
Exit4 HALT
PromptMsg .FILL x000A
.STRINGZ "Enter a command:"
NegX .FILL xFFA8
NegC .FILL xFFBD
NegPlus .FILL xFFD5
NegMinus .FILL xFFD3
NegMult .FILL xFFD6
NegD .FILL xFFBC
; This algorithm takes a sequence of ASCII digits typed by the user,
; converts it into a binary value by calling the ASCIItoBinary
; subroutine and pushes the binary value onto the stack.
;
PushValue LEA R1,ASCIIBUFF ; R1 points to string being
LD R2,MaxDigits ; generated
;
ValueLoop ADD R3,R0,xFFF6 ; Test for carriage return
BRz GoodInput
ADD R2,R2,#0
BRz TooLargeInput
ADD R2,R2,#-1 ; Still room for more digits
STR R0,R1,#0 ; Store last character read
ADD R1,R1,#1
GETC
OUT ; Echo it
BRnzp ValueLoop
;
GoodInput LEA R2,ASCIIBUFF
NOT R2,R2
ADD R2,R2,#1
ADD R1,R1,R2 ; R1 now contains no. of char.
JSR ASCIItoBinary
JSR PUSH
BRnzp NewCommand
;
TooLargeInput GETC ; Spin until carriage return
OUT
ADD R3,R0,xFFF6
BRnp TooLargeInput
LEA R0,TooManyDigits
PUTS
BRnzp NewCommand
TooManyDigits .FILL x000A
.STRINGZ "Too many digits"
MaxDigits .FILL x0003
; This algorithm POPs a value from the stack and puts it in
; R0 before returning to the calling program. R5 is used to
; report success (R5=0) or failure (R5=1) of the POP operation.
POP LEA R0,StackBase
NOT R0,R0
ADD R0,R0,#1 ; R0 = -addr.ofStackBase
ADD R0,R0,R6 ; R6 = StackPointer
BRz Underflow
LDR R0,R6,#0 ; The actual POP
ADD R6,R6,#1 ; Adjust StackPointer
AND R5,R5,#0 ; R5 <-- success
RET
Underflow ST R7,Save ; TRAP/RET needs R7
LEA R0,UnderflowMsg
PUTS ; Print error message.
LD R7,Save ; Restore R7
AND R5,R5,#0
ADD R5,R5,#1 ; R5 <-- failure
RET
Save3 .FILL x0000
StackMax .BLKW 9
StackBase .FILL x0000
UnderflowMsg .FILL x000A
.STRINGZ "Error: Too Few Values on the Stack."
; This algorithm PUSHes on the stack the value stored in R0.
; R5 is used to report success (R5=0) or failure (R5=1) of
; the PUSH operation.
;
PUSH ST R1,Save1 ; R1 is needed by this routine
LEA R1,StackMax
NOT R1,R1
ADD R1,R1,#1 ; R1 = - addr. of StackMax
ADD R1,R1,R6 ; R6 = StackPointer
BRz Overflow
ADD R6,R6,#-1 ; Adjust StackPointer for PUSH
STR R0,R6,#0 ; The actual PUSH
BRnzp Success_exit
Overflow ST R7,Save
LEA R0,OverflowMsg
PUTS
LD R7,Save
LD R1, Save1 ; Restore R1
AND R5,R5,#0
ADD R5,R5,#1 ; R5 <-- failure
RET
Success_exit LD R1,Save1 ; Restore R1
AND R5,R5,#0 ; R5 <-- success
RET
Save2 .FILL x0000
Save1 .FILL x0000
OverflowMsg .STRINGZ "Error: Stack is Full."
; This algorithm calls BinarytoASCII to convert the 2's complement
; number on the top of the stack into an ASCII character string, and
; then calls PUTS to display that number on the screen.
OpDisplay JSR POP ; R0 gets the value to be displayed
ADD R5,R5,#0
BRp NewCommand ; POP failed, nothing on the stack.
JSR BinarytoASCII
LD R0,NewlineChar
OUT
LEA R0,ASCIIBUFF
PUTS
ADD R6,R6,#-1 ; Push displayed number back on stack
BRnzp NewCommand
NewlineChar .FILL x000A
;
; This routine clears the stack by resetting the stack pointer (R6).
;
OpClear LEA R6,StackBase ; Initialize the Stack.
ADD R6,R6,#1 ; R6 is stack pointer
BRnzp NewCommand
.END

1
Contributor
1
Reply
4
Views
10 Years
Discussion Span
Last Post by ae4jm
0

Ladies and Gentleman,

Here is a revised edition of the code. I finally got the code to compile with no errors. When I load the program in the simulator, there is a console window directly behind the simulator display. In this console, printed to the screen is type a command, I believe is the printed message. After this, there is not a lot that I can do. So I've managed to get this far with the program. Guys and Gals, please help me figure this out. What am I doing wrong? Here is a revision of my previously posted code, this is the code that I was able to compile.

Thanks,
Matt

;
; The Calculator, Main Algorithm
;
.ORIG x3000
LEA R6,0001 ; Initialize the Stack.
ADD R6,R6,#-1 ; R6 is stack pointer
LEA R0,PromptMsg
PUTS
GETC
OUT
;
; Check the command
;
Test LD R1,NegX ; Check for X
ADD R1,R1,R0
BRz Exit
;
LD R1,NegC ; Check for C
ADD R1,R1,R0
BRz OpClear ; See Figure 10.27
;
LD R1,NegPlus ; Check for +
ADD R1,R1,R0
BRz OpAdd ; See Figure 10.10
;
LD R1,NegMult ; Check for *
ADD R1,R1,R0
BRz OpMult ; See Figure 10.14
;
LD R1,NegMinus ; Check for -
ADD R1,R1,R0
BRz OpNeg ; See Figure 10.15
;
LD R1,NegD ; Check for D
ADD R1,R1,R0
BRz OpDisplay ; See Figure 10.26
;
; Then we must be entering an integer
;
BRnzp PushValue ; See Figure 10.23
;
NewCommand LEA R0,PromptMsg
PUTS
GETC
OUT
BRnzp Test
Exit HALT
PromptMsg .FILL x000A
.STRINGZ "Enter a command:"
NegX .FILL xFFA8
NegC .FILL xFFBD
NegPlus .FILL xFFD5
NegMinus .FILL xFFD3
NegMult .FILL xFFD6
NegD .FILL xFFBC
; This algorithm takes a sequence of ASCII digits typed by the user,
; converts it into a binary value by calling the ASCIItoBinary
; subroutine and pushes the binary value onto the stack.
;
PushValue LEA R1,ASCIIBUFF ; R1 points to string being
LD R2,MaxDigits ; generated
;
ValueLoop ADD R3,R0,xFFF6 ; Test for carriage return
BRz GoodInput
ADD R2,R2,#0
BRz TooLargeInput
ADD R2,R2,#-1 ; Still room for more digits
STR R0,R1,#0 ; Store last character read
ADD R1,R1,#1
GETC
OUT ; Echo it
BRnzp ValueLoop
;
GoodInput LEA R2,ASCIIBUFF
NOT R2,R2
ADD R2,R2,#1
ADD R1,R1,R2 ; R1 now contains no. of char.
JSR ASCIItoBinary
JSR PUSH
BRnzp NewCommand
;
TooLargeInput GETC ; Spin until carriage return
OUT
ADD R3,R0,xFFF6
BRnp TooLargeInput
LEA R0,TooManyDigits
PUTS
BRnzp NewCommand
TooManyDigits .FILL x000A
.STRINGZ "Too many digits"
MaxDigits .FILL x0003
PUSH LD R1,MAX ; MAX <-- -3FFB
ADD R2,R6,R1
BRz Failure
ADD R6,R6,#-1
STR R0,R6,#0
AND R5,R5,#0
RET
Failure AND R5,R5,#0
ADD R5,R5,#1
RET
MAX .FILL xC005
;
; This routine clears the stack by resetting the stack pointer (R6).
;
OpClear LEA R6,0000 ; Initialize the Stack.
ADD R6,R6,#1 ; R6 is stack pointer
BRnzp NewCommand
; This algorithm calls BinarytoASCII to convert the 2's complement
; number on the top of the stack into an ASCII character string, and
; then calls PUTS to display that number on the screen.
OpDisplay JSR POP ; R0 gets the value to be displayed
ADD R5,R5,#0
BRp NewCommand ; POP failed, nothing on the stack.
JSR BinarytoASCII
LD R0,NewlineChar
OUT
LEA R0,ASCIIBUFF
PUTS
ADD R6,R6,#-1 ; Push displayed number back on stack
BRnzp NewCommand
NewlineChar .FILL x000A
;
; Routine to pop the top two elements from the stack,
; add them, and push the sum onto the stack. R6 is
; the stack pointer.
;
OpAdd JSR POP ; Get first source operand.
ADD R5,R5,#0 ; Test if POP was successful.
BRp Exit ; Branch if not successful.
ADD R1,R0,#0 ; Make room for second operand
JSR POP ; Get second source operand.
ADD R5,R5,#0 ; Test if POP was successful.
BRp Restore1 ; Not successful, put back first.
ADD R0,R0,R1 ; THE Add.
JSR RangeCheck ; Check size of result.
BRp Restore2 ; Out of range, restore both.
JSR PUSH ; Push sum on the stack.
RET ; On to the next task...
Restore2 ADD R6,R6,#-1 ; Decrement stack pointer.
Restore1 ADD R6,R6,#-1 ; Decrement stack pointer.
Exit1 BRnzp NewCommand
;
; Algorithm to pop two values from the stack, multiply them
; and if their product is within the acceptable range, push
; the result on the stack. R6 is stack pointer.
;
OpMult AND R3,R3,#0 ; R3 holds sign of multiplier.
JSR POP ; Get first source from stack.
ADD R5,R5,#0 ; Test for successful POP
BRp Exit ; Failure
ADD R1,R0,#0 ; Make room for next POP
JSR POP ; Get second source operand
ADD R5,R5,#0 ; Test for successful POP
BRp Restore1 ; Failure; restore first POP
ADD R2,R0,#0 ; Moves multiplier, tests sign
BRzp PosMultiplier
ADD R3,R3,#1 ; Sets FLAG: Multiplier is neg
NOT R2,R2
ADD R2,R2,#1 ; R2 contains -(multiplier)
PosMultiplier AND R0,R0,#0 ; Clear product register
ADD R2,R2,#0
BRz PushMult ; Multiplier = 0, Done.
;
MultLoop ADD R0,R0,R1 ; THE actual "multiply"
ADD R2,R2,#-1 ; Iteration Control
BRp MultLoop
;
JSR RangeCheck
ADD R5,R5,#0 ; R5 contains success/failure
BRp Restore4
;
ADD R3,R3,#0 ; Test for negative multiplier
BRz PushMult
NOT R0,R0 ; Adjust for
ADD R0,R0,#1 ; sign of result
PushMult JSR PUSH ; Push product on the stack.
RET
Restore4 ADD R6,R6,#-1 ; Adjust stack pointer.
Restore3 ADD R6,R6,#-1 ; Adjust stack pointer.
Exit2 BRnzp NewCommand
;
; This algorithm takes an ASCII string of three decimal digits and
; converts it into a binary number. R0 is used to collect the result.
; R1 keeps track of how many digits are left to process. ASCIIBUFF
; contains the most significant digit in the ASCII string.
;
ASCIItoBinary AND R0,R0,#0 ; R0 will be used for our result
ADD R1,R1,#0 ; Test number of digits.
BRz DoneAtoB ; There are no digits
;
LD R3,NegASCIIOffset ; R3 gets xFFD0, i.e., -x0030
LEA R2,ASCIIBUFF
ADD R2,R2,R1
ADD R2,R2,#-1 ; R2 now points to "ones" digit
;
LDR R4,R2,#0 ; R4 <-- "ones" digit
ADD R4,R4,R3 ; Strip off the ASCII template
ADD R0,R0,R4 ; Add ones contribution
;
ADD R1,R1,#-1
BRz DoneAtoB ; The original number had one digit
ADD R2,R2,#-1 ; R2 now points to "tens" digit
;
LDR R4,R2,#0 ; R4 <-- "tens" digit
ADD R4,R4,R3 ; Strip off ASCII template
LEA R5,LookUp10 ; LookUp10 is BASE of tens values
ADD R5,R5,R4 ; R5 points to the right tens value
LDR R4,R5,#0
ADD R0,R0,R4 ; Add tens contribution to total
;
ADD R1,R1,#-1
BRz DoneAtoB ; The original number had two digits
ADD R2,R2,#-1 ; R2 now points to "hundreds" digit
;
LDR R4,R2,#0 ; R4 <-- "hundreds" digit
ADD R4,R4,R3 ; Strip off ASCII template
LEA R5,LookUp100 ; LookUp100 is hundreds BASE
ADD R5,R5,R4 ; R5 points to hundreds value
LDR R4,R5,#0
ADD R0,R0,R4 ; Add hundreds contribution to total
;
DoneAtoB RET
NegASCIIOffset .FILL xFFD0
ASCIIBUFF .BLKW 4
LookUp10 .FILL #0
.FILL #10
.FILL #20
.FILL #30
.FILL #40
.FILL #50
.FILL #60
.FILL #70
.FILL #80
.FILL #90
;
LookUp100 .FILL #0
.FILL #100
.FILL #200
.FILL #300
.FILL #400
.FILL #500
.FILL #600
.FILL #700
.FILL #800
.FILL #900
; Algorithm to pop the top of the stack, form its negative,
; and push the result on the stack.
;
OpNeg JSR POP ; Get the source operand
ADD R5,R5,#0 ; test for successful pop
BRp Exit ; Branch if failure
NOT R0,R0
ADD R0,R0,#1 ; Form the negative of the source.
JSR PUSH ; Push the result on the stack.
Exit3 BRnzp NewCommand
;
; Routine to check that the magnitude of a value is
; between -999 and +999.
;
RangeCheck LD R5,Neg999
ADD R4,R0,R5 ; Recall that R0 contains the
BRp BadRange ; result being checked.
LD R5,Pos999
ADD R4,R0,R5
BRn BadRange
AND R5,R5,#0 ; R5 <-- success
RET
BadRange ST R7,Save ; R7 is needed by TRAP/RET
LEA R0,RangeErrorMsg
TRAP x22 ; Output character string
LD R7,Save
AND R5,R5,#0 ;
ADD R5,R5,#1 ; R5 <-- failure
RET
Neg999 .FILL #-999
Pos999 .FILL #999
Save .FILL x0000
RangeErrorMsg .FILL x000A
.STRINGZ "Error: Number is out of range."
POP LD R1,EMPTY ; EMPTY <-- -x4000
ADD R2,R6,R1
BRz Failure
LDR R0,R6,#0
ADD R6,R6,#1
AND R5,R5,#0
RET
Failure1 AND R5,R5,#0
ADD R5,R5,#1
RET
EMPTY .FILL xC000
;
; Subroutines for carrying out the PUSH and POP functions. This
; program works with a stack consisting of memory locations x3FFF
; (BASE) through x3FFB (MAX). R6 is the stack pointer.
;
POP1 ST R2,Save2 ; are needed by POP.
ST R1,Save1
LD R1,BASE ; BASE contains -x3FFF.
ADD R1,R1,#-1 ; R1 contains -x4000.
ADD R2,R6,R1 ; Compare stack pointer to x4000
BRz fail_exit ; Branch if stack is empty.
LDR R0,R6,#0 ; The actual "pop."
ADD R6,R6,#1 ; Adjust stack pointer
BRnzp success_exit
PUSH1 ST R2,Save2 ; Save registers that
ST R1,Save1 ; are needed by PUSH.
LD R1,MAX ; MAX contains -x3FFB
ADD R2,R6,R1 ; Compare stack pointer to -x3FFB
BRz fail_exit ; Branch if stack is full.
ADD R6,R6,#-1 ; Adjust stack pointer
STR R0,R6,#0 ; The actual "push"
success_exit LD R1,Save1 ; Restore original
LD R2,Save2 ; register values.
AND R5,R5,#0 ; R5 <-- success.
RET
fail_exit LD R1,Save1 ; Restore original
LD R2,Save2 ; register values.
AND R5,R5,#0
ADD R5,R5,#1 ; R5 <-- failure.
RET
BASE .FILL xC001 ; BASE contains -x3FFF.
MAX1 .FILL xC005
Save1 .FILL x0000
Save2 .FILL x0000
;
; This algorithm takes the 2's complement representation of a signed
; integer, within the range -999 to +999, and converts it into an ASCII
; string consisting of a sign digit, followed by three decimal digits.
; R0 contains the initial value being converted.
;
BinarytoASCII LEA R1,ASCIIBUFF ; R1 points to string being generated
ADD R0,R0,#0 ; R0 contains the binary value
BRn NegSign ;
LD R2,ASCIIplus ; First store the ASCII plus sign
STR R2,R1,#0
BRnzp Begin100
NegSign LD R2,ASCIIminus ; First store ASCII minus sign
STR R2,R1,#0
NOT R0,R0 ; Convert the number to absolute
ADD R0,R0,#1 ; value; it is easier to work with.
;
Begin100 LD R2,ASCIIoffset ; Prepare for "hundreds" digit
;
LD R3,Neg100 ; Determine the hundreds digit
Loop100 ADD R0,R0,R3
BRn End100
ADD R2,R2,#1
BRnzp Loop100
;
End100 STR R2,R1,#1 ; Store ASCII code for hundreds digit
LD R3,Pos100
ADD R0,R0,R3 ; Correct R0 for one-too-many subtracts
;
LD R2,ASCIIoffset ; Prepare for "tens" digit
;
Begin10 LD R3,Neg10 ; Determine the tens digit
Loop10 ADD R0,R0,R3
BRn End10
ADD R2,R2,#1
BRnzp Loop10
;
End10 STR R2,R1,#2 ; Store ASCII code for tens digit
ADD R0,R0,#10 ; Correct R0 for one-too-many subtracts
Begin1 LD R2,ASCIIoffset ; Prepare for "ones" digit
ADD R2,R2,R0
STR R2,R1,#3
RET
;
ASCIIplus .FILL x002B
ASCIIminus .FILL x002D
ASCIIoffset .FILL x0030
Neg100 .FILL xFF9C
Pos100 .FILL x0064
Neg10 .FILL xFFF6
; This algorithm POPs a value from the stack and puts it in
; R0 before returning to the calling program. R5 is used to
; report success (R5=0) or failure (R5=1) of the POP operation.
POP5 LEA R0,StackBase
NOT R0,R0
ADD R0,R0,#1 ; R0 = -addr.ofStackBase
ADD R0,R0,R6 ; R6 = StackPointer
BRz Underflow
LDR R0,R6,#0 ; The actual POP
ADD R6,R6,#1 ; Adjust StackPointer
AND R5,R5,#0 ; R5 <-- success
RET
Underflow ST R7,Save ; TRAP/RET needs R7
LEA R0,UnderflowMsg
PUTS ; Print error message.
LD R7,Save ; Restore R7
AND R5,R5,#0
ADD R5,R5,#1 ; R5 <-- failure
RET
Save6 .FILL x0000
StackMax .BLKW 9
StackBase .FILL x0000
UnderflowMsg .FILL x000A
.STRINGZ "Error: Too Few Values on the Stack."
.END

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.