CS306 Processing Systems and Structures Lockwood, Spring 2002

Machine Problem 2: Stack-based Calculator

Assigned Thursday 2/06/2002
Due Date Thursday 2/14/2002
Purpose Math, Stack, Subroutines.
Points50

Introduction

Stack-based calculators use 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 stack-based calculators, there is no need to use parenthesis or equal buttons.

On a stack-based calculator, 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 stack-based 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, there are three modular procedures.
You will need to write two of the procedures (Calculate and FormatOutput)

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)

.___________ CS306 Stack Calculator ____________.
| Enter Number                              -or-|
|      Operation (+,-,*,/,%,!,N,&,|,^,~)    -or-|
|      Mode (MD=Decimal, MH=Hex, MB=Binary) -or-|
|      Quit (ESC, Q, or q)                      |
|____________ Lockwood: Spring 2002 ____________|

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 3.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

MP2.ASM

; Stack-based Calculator

; You Name Here : ____________________________________

; CS306: Machine Problem 2
; Spring 2002
; Prof. John W. Lockwood
; Washington University, Department of Computer Science

; Ver. 3.1

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

MAXBUFLENGTH EQU 80 ; Maximum length of an input line

;====== External Functions ===============================================
;-- lib306 Calls --
extern kbdine, dspmsg, binasc, dspout

;-- LibMP2 Calls --
extern LibProcessInput   ; This routine is given to you for free!
extern LibCalculate      ; Your code will replace the call to this function
extern LibFormatOutput   ; Your code will replace the call to this function
extern mp2xit            ; Call this to exit the program

;-- Variables used by LibMP2 --
GLOBAL DispMode 
GLOBAL InputBuffer 
GLOBAL BufLength 
GLOBAL OutputBuffer 

;====== Stack ============================================================
SEGMENT stkseg STACK                    ; *** STACK SEGMENT ***
        resb      64*8
stacktop:

;====== Begin Code/Data ===================================================
SEGMENT code                            ; *** CODE SEGMENT ***

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

DispMode DW     10      ; Operate in decimal mode by default

crlf DB CR,LF,'$'       ; New Line

HelpMsg  db '.___________ CS306 Stack 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 2002 ____________|',CR,LF,CR,LF,'$'

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

OutputBuffer db '................$' ; Contains formatted output 
                                    ; terminated with '$'

InputBuffer  db '........................................'
             db '........................................$'
             ; Contains one line of user input
BufLength    dw 0 ; Actual Length of InputBuffer


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

ProcessKey: 
 ; 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     word [BufLength]     ; Proceed to next byte.

  ProcessKeyFinished:
        RET

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


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

Calculate:

        ; Write Your code here !

        RET

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

FormatOutput:

        ; Write Your code here !

        RET

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

..start:
        MOV     ax, cs                  ; Initialize Default Segment register
        MOV     ds, ax 
        MOV     ax, stkseg              ; Initialize Stack Segment register
        MOV     ss, ax
        MOV     sp, stacktop            ; Initialize Stack Pointer register

MAIN:

        MOV     DX, HelpMsg ; Print on-line help
        CALL    dspmsg

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

          MOV    word [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,LF
          JE     KeyDone             ; Continue reading until end-of-line
          CMP    AL,CR
          JE     KeyDone             ; Continue reading until end-of-line
          JMP KeyLoop

KeyDone:

          MOV    DX, crlf            ; Skip a line
          CALL   dspmsg 

          Call    LibProcessInput    ; -- Process InputBuffer --
                                     ; (This routine is given to you for free)

          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, ResultMsg
          Call    dspmsg             ; Print 'Result: '
          MOV     DX, OutputBuffer
          Call    dspmsg             ; Print formatted output 
          MOV     dx,crlf
          call    dspmsg             ; Print New line

          JMP     MainLoop

Done:     call    mp2xit             ; Exit program

 

Copyright 1996-2002 John Lockwood