Question: 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
Get step-by-step solutions from verified subject matter experts
