ARM Program: Stack calculator

This program should read the values of an array one at a time, and based on the value in the array location, perform some arithmetic operation on values on a stack.

The following are numeric values of arithmetic operations:

Here are a few small arithmetic script examples:

  SCRIPT1 = 0, 100, 0 200, 1, 0, 3, 3, 0, 10, 2, 254, 255

The script is translated into this: push 100, push 200, add, push 3, multiply, push 10, subtract, display, exit.

After push 100, push 200 are evaluated, the stack looks like this:

      |     |<- sp 
      |-----|

      | 200 |

      |-----|      
      | 100 |
      |-----|
 

The add instruction pops the top two numbers, adds them together, and pushes the result. After the first add is evaluated, the stack looks like this:

 

      |     | <- sp
      |-----|
      | 300 |
      |-----|

When the example script given above is run, it displays the single number 890.

Your assembly language program must be general enough to run any script specified in the data area of your program.

To run the script, read the first value in the script. Based on that value, call a subroutine. The ``0'' subroutine reads the next value in the script and push it on the stack, and then returns. The ``1'' subroutine pops 2 values from the stack, adds them, pushes the result, and returns. Etc.

You should designate one register, say r12, as your script array index. This register will always point to the current element in the array of script numbers (instructions).

The main body of the program is a loop which:

It does this repeatedly until subroutine ``255'', the exit subroutine, is executed.

 

Hints:

-you will need to design a “case statement”

 

- a display function which converts from a number to a string ascii codes which can be printed.

 

to convert a hex digit to ascii

            AREA   asciit, CODE, READONLY

SWI_WriteC   EQU    &0

SWI_Exit        EQU    &11

Mask               EQU 0x0000000F

 

            ENTRY

start

            LDR    r0, Digit          ;load digit

            LDR    r1, Result        ;address for result

 

            CMP    r0, #0xA          ;is the number < 10 decimal

            BLT     Add_0             ; then branch

            ADD    r0, r0, #"A"-"0"-0xA ;add offset for 'A' to 'F'

 

Add_0 ADD    r0, r0, #"0"      ;convert to ASCII

            STR     r0,[r1]

           

            SWI     SWI_WriteC   ;ouput it

            SWI     SWI_Exit        ;all done

 

            AREA   Data1, DATA

 

Digit    DCD    &0C

 

            AREA   Data2, DATA

 

Result  DCD    0

 

            END