Answered step by step
Verified Expert Solution
Question
1 Approved Answer
I need help coding this lc3 assembly program. Basically I need to make a calculator using LC3 assembly language and perform + - * and
I need help coding this lc3 assembly program. Basically I need to make a calculator using LC3 assembly language and perform + - * and / operations. It works fine but.... ***I want to edit it so that it can also do addition and so it can accept up to 4 integers as input numbers. Currently, it accepts single digit input numbers*** The code:
.ORIG x3000 | |
START: | |
; clear registers that are used | |
AND R0, R0, 0 | |
AND R1, R0, 0 | |
AND R2, R0, 0 | |
; print greetings and get input | |
LEA R0, GREETING | |
PUTS | |
GETC | |
PUTC | |
ADD R1, R0, 0 | |
LEA R0, FOLLOWUP | |
PUTS | |
GETC | |
PUTC | |
ADD R2, R0, 0 | |
; subtract the ASCII offset from the numbers to convert them from their ASCII values | |
LD R0, ASCIIOFFSET | |
ADD R1, R1, R0 | |
ADD R2, R2, R0 | |
; perform operations and store answers in the designated memory locations | |
JSR SUBTRACT | |
JSR MULTIPLY | |
JSR DIVIDE | |
; convert back to ASCII | |
LD R0, ASCIIOFFSET | |
NOT R0, R0 | |
ADD R0, R0, #1 | |
ADD R1, R1, R0 | |
ADD R2, R2, R0 | |
; print results | |
ST R1, INPUT1 | |
ST R2, INPUT2 | |
LEA R0, NEWLINE | |
PUTS | |
LD R0, INPUT1 | |
PUTC | |
LEA R0, MINUS | |
PUTS | |
LD R0, INPUT2 | |
PUTC | |
LEA R0, EQUALS | |
PUTS | |
LDI R0, SUBRESULT2 | |
PUTC | |
LEA R0, NEWLINE | |
PUTS | |
LD R0, INPUT1 | |
PUTC | |
LEA R0, TIMES | |
PUTS | |
LD R0, INPUT2 | |
PUTC | |
LEA R0, EQUALS | |
PUTS | |
JSR PRINTMULT ; subroutine to print bigger values properly | |
LEA R0, NEWLINE | |
PUTS | |
LD R0, INPUT1 | |
PUTC | |
LEA R0, DIVIDEDBY | |
PUTS | |
LD R0, INPUT2 | |
PUTC | |
LEA R0, EQUALS | |
PUTS | |
LDI R0, DIVRESULT2 | |
PUTC | |
LEA R0, REMAINDING | |
PUTS | |
LDI R0, REMAINDER2 | |
PUTC | |
; store values into x3100-3103 as required, after dealing with the subroutine that uses those lines | |
LD R0, SUBRESULT2 | |
ST R0, SUBRESULT | |
LD R0, MULRESULT2 | |
ST R0, MULRESULT | |
LD R0, DIVRESULT2 | |
ST R0, DIVRESULT | |
LD R0, REMAINDER2 | |
ST R0, REMAINDER | |
; finish off with a newline and loop | |
LEA R0, NEWLINE | |
PUTS | |
BR START | |
HALT | |
; strings | |
GREETING: .STRINGZ "This program will perform operations on your input. Please enter a single-digit number: " | |
FOLLOWUP: .STRINGZ " Now enter another one: " | |
NEWLINE: .STRINGZ " " | |
MINUS: .STRINGZ " - " | |
TIMES: .STRINGZ " * " | |
DIVIDEDBY: .STRINGZ " / " | |
REMAINDING: .STRINGZ " R" | |
EQUALS: .STRINGZ " = " | |
; variables | |
ASCIIOFFSET: .FILL #-48 | |
SUBRESULT: .FILL x3100 | |
MULRESULT: .FILL x3101 | |
DIVRESULT: .FILL x3102 | |
REMAINDER: .FILL x3103 | |
INPUT1: .FILL 0 | |
INPUT2: .FILL 0 | |
TEMP: .FILL 0 | |
; for the weird line overwriting | |
SUBRESULT2: .FILL x3140 | |
MULRESULT2: .FILL x3141 | |
DIVRESULT2: .FILL x3142 | |
REMAINDER2: .FILL x3143 | |
; functions/subroutines | |
SUBTRACT: | |
; clear used registers again | |
AND R0, R0, 0 | |
AND R3, R0, 0 | |
NOT R4, R2 ; flip digit 2's (R2's) sign and store in R4 | |
ADD R4, R4, #1 | |
; subtract R1 by R4=R2 and store in R3 | |
ADD R3, R1, R4 | |
; convert back to ASCII | |
LD R0, ASCIIOFFSET | |
NOT R0, R0 | |
ADD R0, R0, #1 | |
ADD R3, R3, R0 | |
STI R3, SUBRESULT2 ; store answer | |
RET | |
MULTIPLY: | |
; clear used registers again | |
AND R0, R0, 0 | |
AND R3, R0, 0 | |
AND R4, R0, 0 | |
ADD R4, R2, 0 ; store loop incrementer (R2) in R4 | |
; multiply R1 by R2 and store in R3 | |
LOOP1: | |
ADD R3, R3, R1 ; add R1 to R3 R4=R2 times | |
ADD R4, R4, #-1 | |
BRp LOOP1 ; break if R4 is <=0 | |
STI R3, MULRESULT2 ; store answer | |
RET | |
DIVIDE: | |
; clear used registers again | |
AND R0, R0, 0 | |
AND R3, R0, 0 | |
AND R5, R0, 0 | |
AND R6, R0, 0 | |
ADD R5, R1, 0 ; store R1 in R5 so we can mess with R1's value | |
NOT R4, R2 ; flip R2's sign again and store in R4 | |
ADD R4, R4, #1 | |
; divide R1 by R2 and store dividend in R3 | |
LOOP2: | |
ADD R3, R3, #1 ; keep track of how many times it divides | |
ADD R5, R5, R4 ; keep subtracting by divisor | |
AND R6, R0, 0 ; use R6 as a buffer so that we break when R4>R5 | |
ADD R6, R5, 0 | |
ADD R6, R6, R4 | |
BRzp LOOP2 ; break if R6 is <0 | |
; convert back to ASCII | |
LD R0, ASCIIOFFSET | |
NOT R0, R0 | |
ADD R0, R0, #1 | |
ADD R3, R3, R0 | |
ADD R5, R5, R0 | |
STI R3, DIVRESULT2 ; store answer | |
STI R5, REMAINDER2 ; store remainder | |
RET | |
PRINTMULT: | |
; the compiler was putting the lines in this subroutine on x3100-3103, and so they were overwritten | |
; I had to store the results in a different location and then put them back at the end | |
; clear used registers again | |
AND R3, R0, 0 | |
AND R4, R0, 0 | |
AND R5, R0, 0 | |
ADD R5, R7, 0 ; store RET value before using traps | |
; get result into R0 | |
LDI R0, MULRESULT2 | |
; test for a small enough number to just print one digit | |
ADD R3, R0, 0 ; store quotient in R3 in case we branch | |
ADD R4, R0, #-10 | |
BRn ONEDIGIT | |
; clear used registers again | |
AND R3, R0, 0 | |
AND R4, R0, 0 | |
; divide by 10 and find remainder | |
LOOP3: | |
ADD R3, R3, #1 ; keep track of how many times it divides | |
ADD R0, R0, #-10 ; keep subtracting by divisor | |
AND R4, R0, 0 ; use R4 as a buffer so that we break when 10>R4 | |
ADD R4, R0, 0 | |
ADD R4, R4, #-10 | |
BRzp LOOP3 ; break if R4 is <0 | |
; test for a quotient of 0 and if so, just print remainder (which is R0) | |
AND R4, R0, 0 | |
ADD R4, R3, #-1 | |
BRz DIVTEST | |
DIVTESTFAIL: | |
; print quotient and then load remainder to print | |
AND R4, R0, 0 | |
ADD R4, R0, 0 ; store remainder to print quotient first | |
; convert back to ASCII before printing | |
LD R0, ASCIIOFFSET | |
NOT R0, R0 | |
ADD R0, R0, #1 | |
ADD R3, R3, R0 | |
; store final value to print in a variable and load it into R0 so that PUTC is happy | |
ST R3, TEMP | |
LD R0, TEMP | |
PUTC | |
; put remainder in R3 to print | |
AND R3, R0, 0 | |
ADD R3, R4, 0 | |
ONEDIGIT: | |
; convert back to ASCII before printing | |
LD R0, ASCIIOFFSET | |
NOT R0, R0 | |
ADD R0, R0, #1 | |
ADD R3, R3, R0 | |
; store final value to print in a variable and load it into R0 so that PUTC is happy | |
ST R3, TEMP | |
LD R0, TEMP | |
PUTC | |
; restore RET value before going back | |
AND R7, R0, 0 | |
ADD R7, R5, 0 | |
RET | |
; test for a quotient of 0: if INPUT1 <= INPUT2, quotient is 0 | |
DIVTEST: | |
LD R4, INPUT1 | |
NOT R4, R4 | |
ADD R4, R4, #1 | |
AND R6, R0, 0 | |
LD R6, INPUT2 | |
ADD R4, R4, R6 | |
BRn DIVTESTFAIL | |
AND R3, R0, 0 | |
ADD R3, R0, 0 | |
BRzp ONEDIGIT | |
; end of code | |
.END |
Thanks!
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started