ECE291 Computer Engineering II Lockwood, Spring 1999

Machine Problem 2: RPN Calculator

Assigned Thursday 2/11/99
Due Date Thursday 2/25/99
Purpose Math, Stack, Subroutines.
Points50

Introduction

Calculators were one of the greatest gifts to the engineer this century. They eliminated the tedious work of calculating numeric results. Hewlett-Packard (HP) innovated a method of calculation called RPN (Reverse Polish Notation).

RPN employs a stack to hold numbers and intermediate results. When a number is entered, it is PUSHed to the stack. When an operation is entered, it POPs element(s) from the stack, performs the calculation, and PUSHes the result back to the stack. With RPN, there is no need for parenthese or equal buttons.

Using RPN, the equation X+(Y*Z) can be computed by entering the following keystrokes:

X [enter] Y [enter] Z [enter] * [enter] + [enter]

For this example, X, Y, and Z were pushed to the stack. When the multiplication command was entered (*); the values Y and Z were POPed from the stack, Y*Z was computed, and this product (YZ) was PUSHed back to the stack. When the addition command was entered (+), X and YZ were POPed from the stack, X+YZ was computed, and this sum was pushed back to the stack. The final result is stored at the top of the stack.

Problem Description

For this machine problem, you will implement the core functionality of a RPN calculator. Your calculator will compute results on 16-bit integer values. It will read and print results in binary, decimal, or hex. It will support all standard logical and mathematical operations, including the computation of factorials.

Implementation

For this program, you will write three modular procedures.

Program Assignment

You will begin this machine problem with a fully functional program. The main program is given below. I have provided the library routines for each of the three procedures above. You will score points by replacing the library procedures with your own code. Your score will be proportional to the percentage of the code that you write yourself. The breakdown in points is given below: Your routine MUST perform all functions of the subroutine to obtain credit.

Sample Input (MP2.IN)

150     ; First Number [base 10 by default] pushed to stack
50      ; Second Number pushed to stack
-       ; Calculate: 150-50=100 , Leave Result on stack
8
2
5
*       
+       ; Calculate: (2*5)+8=18 , Leave Result on stack
/       ; Calculate: 100/18=5 (Integer Arithmetic)
N       ; Calculate: Negate(5)=-5
12      ; Enter 12
+       ; Calculate: -5+12=7
!       ; Calculate: Factorial(7)=7*6*5*4*3*2*1=5040
MH      ; Switch to Hex Mode (Enter/Display format): 5040d = 13B0h
FFF     ; Enter FFF (hex)
+       ; Calculate: 13B0h+0FFFh=23AFh
2300    ; Enter 2300 (hex)
-       ; Calculate: 23AFh-2300h=00AFh (hex)
MB      ; Switch to Binary Mode: 00AFh=0000000010101111b
111111  ; Enter 111111 (binary)
&       ; Calculate: Logical AND = 0000000000101111
000111  ; Enter 000111 (binary) (note that preceding zeros ignored)
^       ; Calculate: Logical XOR = 0000000000101000
11      ; Enter 11 (binary)
|       : Calculate: Logical  OR = 0000000000101011
~       ; Calculate: Logical NOT = 1111111111010100
MH      ; Switch to Hex Mode: Final Result == FFD4h
Q       ; Escape to exit

Sample Output (MP2.OUT)

============ ECE291 RPN Calculator ============
Enter Number                               -or-
      Operation (+,-,*,/,%,!,N,&,|,^,~)    -or-
      Mode (MD=Decimal, MH=Hex, MB=Binary) -or-
      Quit (ESC, Q, or q)
============ Lockwood: Spring 1999 ============

150     ; First Number [base 10 by default] pushed to stack
Result: 150
50      ; Second Number pushed to stack
Result: 50
-       ; Calculate: 150-50=100 , Leave Result on stack
Result: 100
8
Result: 8
2
Result: 2
5
Result: 5
*       
Result: 10
+       ; Calculate: (2*5)+8=18 , Leave Result on stack
Result: 18
/       ; Calculate: 100/18=5 (Integer Arithmetic)
Result: 5
N       ; Calculate: Negate(5)=-5
Result: -5
12      ; Enter 12
Result: 12
+       ; Calculate: -5+12=7
Result: 7
!       ; Calculate: Factorial(7)=7*6*5*4*3*2*1=5040
Result: 5040
MH      ; Switch to Hex Mode (Enter/Display format): 5040d = 13B0h
Result: 13B0
FFF     ; Enter FFF (hex)
Result: 0FFF
+       ; Calculate: 13B0h+0FFFh=23AFh
Result: 23AF
2300    ; Enter 2300 (hex)
Result: 2300
-       ; Calculate: 23AFh-2300h=00AFh (hex)
Result: 00AF
MB      ; Switch to Binary Mode: 00AFh=0000000010101111b
Result: 0000000010101111
111111  ; Enter 111111 (binary)
Result: 0000000000111111
&       ; Calculate: Logical AND = 0000000000101111
Result: 0000000000101111
000111  ; Enter 000111 (binary) (note that preceding zeros ignored)
Result: 0000000000000111
^       ; Calculate: Logical XOR = 0000000000101000
Result: 0000000000101000
11      ; Enter 11 (binary)
Result: 0000000000000011
|       ; Calculate: Logical  OR = 0000000000101011
Result: 0000000000101011
~       ; Calculate: Logical NOT = 1111111111010100
Result: 1111111111010100
MH      ; Switch to Hex Mode: Final Result == FFD4h
Result: FFD4
Q       ; Escape to exit

LIBMP2 Ver 2.1 Calls: 
 -FormatOutput    
 -ProcessInput    
 -Calculate       

Preliminary Procedure

Final Steps

  1. Download and print the MP2 grading sheet from the web site.
  2. Verify that your program meets all requirements for handin.
  3. Demonstrate MP2.EXE to a TA or to the instructor. You will then be asked to recompile and demonstrate MP2 with different database files. Your program must work with all given input. Once approved, you are ready to turn in your program.
  4. You will be asked to run your calculator with the input file MP2.IN by executing the following command.
    MP2 < MP2.IN The output should match MP2.OUT.
  5. You will be asked to run your calculator with another input file to verify that no numbers or results are hardcoded into your program.
  6. Be prepared to answer questions about any aspect of the operation of your program. The TAs will not accept an MP if you cannot fully explain the operation of your code.
  7. Print MP2.ASM and give it to to the same TA which approved your demonstration. Be sure that your name is the printout.
  8. Electrically submit your programs to the TA's handin floppy:
    A:\HANDIN MyWindowsLogin

MP2.ASM

        PAGE 75, 132
        TITLE   MP2     your name       current date

COMMENT % RPN Calculator

          ECE291: Machine Problem 2
          Prof. John W. Lockwood
          University of Illinois
          Dept. of Electrical & Computer Engineering
          Spring 1999
          
          Ver. 2.1
        %

;====== Constants ========================================================
CR      EQU 13
LF      EQU 10
BSKEY   EQU 8
ESCKEY  EQU 27
SPACE   EQU 32
SEMI    EQU 59

;====== External Functions ===============================================
;-- Lib291 Calls --
extrn kbdine:near, dspmsg:near, binasc:near, dspout:near

;-- LibMP2 Calls --
extrn LibProcessInput:near ; Your code will replace the call to this function
extrn LibCalculate:near    ; Your code will replace the call to this function
extrn LibFormatOutput:near ; Your code will replace the call to this function
extrn mp2xit:near

;====== Stack ============================================================
stkseg  segment stack                   ; *** STACK SEGMENT ***
        db      64 dup ('STACK   ')     ; 64*8 = 512 Bytes of Stack
stkseg  ends

;====== Begin Code/Data ===================================================
cseg    segment public 'CODE'           ; *** CODE SEGMENT ***
        assume  cs:cseg, ds:cseg, ss:stkseg, es:nothing

;====== Variables =============

DispMode DW     10      ; Operate in decimal mode by default
crlf DB CR,LF,'$'       ; New Line

HelpMsg  db '============ ECE291 RPN Calculator ============',CR,LF
         db 'Enter Number                               -or-',CR,LF
         db '      Operation (+,-,*,/,%,!,N,&,|,^,~)    -or-',CR,LF
         db '      Mode (MD=Decimal, MH=Hex, MB=Binary) -or-',CR,LF
         db '      Quit (ESC, Q, or q)',CR,LF
         db '============ Lockwood: Spring 1999 ============',CR,LF,CR,LF,'$'

ResultMsg db 'Result: ','$'   ; Message displayed on screen before output

OutputBuffer db 16 dup(?),'$' ; Contains formatted output 
                              ; (Should be terminated with '$')

MAXBUFLENGTH EQU 80           ; Maximum length of an input line
InputBuffer  db MAXBUFLENGTH dup(?),'$' ; Contains one line of user input
BufLength    dw ?                       ; Actual Length of InputBuffer

PUBLIC DispMode, InputBuffer, BufLength, OutputBuffer ; Needed by LIBMP2

;====== Your procedures =======

ProcessKey PROC NEAR
 ; Input:
 ;    Register AL == ASCII code for key that was entered
 ;    (value of register AL must be preserved)
 ; Output:
 ;    Variable InputBuffer == String containing one line of input
 ; Input/Output:
 ;    BufLength == Length of InputBuffer
 ; Purpose:
 ;    Enqueue each character entered from the keyboard
 ;    into a string called 'InputBuffer'.
 ;    
 ; Note:
 ;    This code is given to you for free as an example
 ;    of how to write function headers, label jumps, and comment your code.
 ;

        MOV     DI, BufLength        ; Load existing string length

        CMP     AL,BSKEY             ; Check if user hit 'Back space' key
        JE      ProcessBackSpaceKey

        CMP     DI, MAXBUFLENGTH     ; Avoid Buffer Overflow!
        JAE     ProcessKeyFinished

        MOV     InputBuffer[DI],AL   ; Append input letter to buffer 

        INC     BufLength            ; Proceed to next byte.

  ProcessKeyFinished:
        RET

  ProcessBackSpaceKey:
        CMP DI,0                    ; If string is not already empty .. 
        JE ProcessKeyFinished
        DEC BufLength  
        RET                         ; .. make it 1 byte shorter 

ProcessKey ENDP

; ------------------

ProcessInput PROC Near
        ; Write Your code here !
        RET
ProcessInput ENDP

; ------------------

FormatOutput PROC Near
        ; Write Your code here !
        RET
FormatOutput ENDP

; ------------------

Calculate PROC Near
        ; Write Your code here !
        RET
Calculate ENDP


;====== Main procedure =========


main      proc    far
          mov     ax, cseg   ; Initialize DS register
          mov     ds, ax

          MOV     DX, offset HelpMsg ; Print on-line help
          CALL    DSPMSG

MainLoop:   ; --- Main body of program ---

          MOV    BufLength, 0   

KeyLoop:  Call   KBDINE              ; Read keyboard input

          Call   ProcessKey          ; -- Process Keyboard Input ---
          CMP    AL,ESCKEY
          JE     Done                ; Quit instantly for ESCAPE key
          CMP    AL,13
          JNE KeyLoop                ; Continue reading until end-of-line

          MOV    DX, offset crlf     ; Skip a line
          CALL   DSPMSG 

          Call    LibProcessInput    ; -- Process InputBuffer --
                                     ; (Replace with your 'Call ProcessInput')

          CMP    BH,'Q'
          JE     Done                ; Quit for 'Q' or 'q' command
          CMP    BH,'q'
          JE     Done


          Call    LibCalculate       ; -- Perform Math/Logical Calculation --
                                     ; (Replace with your 'Call Calculate')


          Call    LibFormatOutput    ; -- Format number at top of stack --
                                     ; (Replace with your 'Call FormatOutput')


          MOV     DX, Offset ResultMsg
          Call    DSPMSG             ; Print 'Result: '
          MOV     DX, Offset OutputBuffer
          Call    DSPMSG             ; Print formatted output 
          MOV     dx,offset crlf
          call    DSPMSG             ; Print New line

          JMP     MainLoop

Done:     call    mp2xit             ; Exit program

main    endp
 
cseg    ends
        end     main