In this final problem you will design and program a small calculator program in the LC-3 language. You will be demonstrating a beginning competence in assembly programming. You will learn how to use subroutines and input/output capabilities in a simple program.
The LC-3 tiny 4-function calculator will perform addition, subtraction, multiplication, and division using two operands entered by a user. All of the math will be single precision (i.e. contained within a 16-bit register size) and we will artificially limit the magnitude of the inputs so as not to allow overflow conditions (to keep it simple).
The program will consist of a main portion that will initialize the computer registers and enter a loop in which it prints a menu of options for the user, calculate or exit. If the user selects calculate the user will enter two operands and then select which operation (+, -, *, or /) to perform. The operands will be integers and the division will produce an integer result and remainder. The results will be displayed on the console with a message and when the user presses the ENTER key, the menu will be displayed again. See the console screens below.
The program will use subroutines to get user menu selections, operands, and operation selections. It will use TRAP commands given in Table A.2 on page 543 (trap vectors and alternate mnemonics are listed with the functions performed.)
The program will do as follows:
1. Initialize registers for data and for handling loops, etc. then enter a loop that terminates when the user selects exit. 2. Print the message: "LC-3 Tiny Calculator" followed by a return-line feed. 3. Print the one line menu message and prompt: "1) Calculate 2) Quit: _" (the underscore represents the cursor). 4. Get the user input. 5. If the user entered a '2' branch to the exit label (HALT), otherwise goto 6. 6. Prompt the user for the first operand: "Enter a two-digit decimal number: __" followed by a return-line feed. 7. Get the user's operand input, convert it to an integer value for storage in a register or memory. 8. Prompt the user for the second operand: "Enter a two-digit decimal number: __" followed by a return-line feed. 9. Get the user's operand input, convert it to an integer value for storage in a register or memory. 10. Prompt the user for the operation choice: "Enter the number of the operation, 1) ADD, 2) SUB, 3) MUL, 4) DIV: _". 11. Get the user's selection (an ascii character '1', '2', '3', or '4'.) 12. Convert the user's selection to an integer and use this to determine which subroutine to call. 13. Branch to the appropriate subroutine and execute the calculation. Note that in the case of division the remainder is to be reported on the screen so the main loop will need to know that it should print out the result and the remainder. 14. Store the result(s) in registers and return to the calling main loop. 15. Print out the result(s): "Result: ___" or "Result: ___ Remainder: ___" followed by a carriage return-line feed. 16. Return to the main menu at #3 above. 17. On exit, print a farewell message (of your choice but keep it clean).
Design the algorithms using flow charting. You may use the Wikipedia article: https://en.wikipedia.org/wiki/Flowchart for reference to how to use the shapes. But emulate the style as shown in Fig. 5.16, page 139. Draw each subroutine as its own independent chart. See below for the subroutines required.
Determine in advance which registers to use for various purposes. Remember R7 is reserved for the return address so do not use it for any other purpose. If you need to nest subroutine calls I will show you how to do this by saving the value in R7 to a temporary memory location. You may need to nest calls more than one level deep. Select registers for passing parameters if needed (e.g R1 and R2) and for return values (e.g. R0, but remember R0 is also used by some of the TRAP commands so be careful). Select the registers to be used for holding data in each of the process boxes in your flowchart and show them in the charts.
You may use any convenient charting tool (e.g. PowerPoint or some other charting tool). Or you may draw them by hand and scan them, however, make sure the diagrams are neat and clear with readable lettering. Make sure you can export the charts to a .png file for import into a Word document. See below for the required documentation of charts and screen shots.The program should be named "tinyCalc.asm". Make sure everyone's names are in the header comments.
The program should have the following subroutines (each with its own chart):
Run your program and after each test (putting in operands, etc.) capture a screen shot. You can upload the screenshot into a Paint drawing and export it as a .png file for later incorporation into a Word document (below). Number the graphic files test1.png, test2.png, etc. for each test. Test each of the four functions twice with different operands. Note that since the program is in a loop, you can actually get several tests into one screenshot. Just make sure they are sequentially numbered and incorporate them in the .docx file accordingly.
It may have occurred to you that I have passed over negative operands! As specified above, you only need to enter two digit positive numbers. To make things a little more interesting, you can earn extra credit (10%) if you modify the operand input routines to accept positive (just two characters) or negative two digit values (three character strings). If you do this you will need to run another set of tests and get screenshots to show the program handling negative numbers correctly. Be sure to note in a header comment that you have implemented this feature.
; get_data.asm - a data entry subroutine example ; ; George Mobus ; ; ; The program demonstrates the use of subroutines, including a two-deep nesting of one subroutine ; calling another subroutine. ; .orig x3000 ; JSR GETDATA ST R1,FIRST AND R5,R5,#0 JSR GETDATA ST R1,SECOND STOP HALT FIRST .BLKW 1 SECOND .BLKW 1 ; ; Subroutine to get a two digit number ; GETDATA ST R7,GDREG7 ; save return address ST R6,GDREG6 ; registers to be used need saving ST R5,GDREG5 ST R2,GDREG2 ; AND R1,R1,#0 AND R2,R2,#0 LEA R0,PROMPT LD R6,THIRTY PUTS GETC OUT ADD R1,R0,#0 ; move R0 to R1 ADD R1,R1,R6 ; subtract x30 from R1 to get digit LD R2,TEN JSR MULT ; multiply R1 by 10 GETC OUT ADD R0,R0,R6 ; subtract x30 from next character ADD R1,R0,R1 ; add two registers to get decimal value LD R0,CR ; output a carriage return OUT LD R0,LF OUT LD R2,GDREG2 LD R5,GDREG5 ; restore register values LD R6,GDREG6 LD R7,GDREG7 RET ; value returned in R1 GDREG7 .BLKW 1 ; use to keep subroutine return address GDREG6 .BLKW 1 ; save registers modified in this subroutine GDREG5 .BLKW 1 GDREG2 .BLKW 1 ; TEN .FILL #10 THIRTY .FILL xFFD0 ; -48 or neg x30 PROMPT .STRINGZ "Enter a two digit number: " CR .FILL #13 ; carriage return LF .FILL #10 ; line feed ; ; ; Subroutine to multiply R5 * R1 ; MULT ST R7,MUREG7 ; save return address ST R3,MUREG3 ; registers to be used need saving ST R5,MUREG5 AND R3,R3,#0 ; R3 will be the result AGAIN ADD R3,R3,R1 ADD R5,R5,#-1 BRp AGAIN AND R1,R1,#0 ; falls through when R5 == 0 or -1 ADD R1,R3,#0 LD R5,MUREG5 LD R3,MUREG3 LD R7,MUREG7 ;restore return address RET ;answer in R1 MUREG7 .BLKW 1 MUREG3 .BLKW 1 MUREG5 .BLKW 1 .END
Prepare a Word document for turning in. It should have all team member names at the top. You will use this to copy/paste the .png files, charts and test run screenshots for submission. Name the file screen.docx.
Zip up the tinyCalc.asm text file, and screen.docx file and submit that zip file as usual. Please name the zip file problem5.zip.