; The M13_SM_RUN.ASM file

.586P
.MODEL FLAT, stdcall     ; Flat memory model

EXTERN NEWARRAY@4:NEAR   ; This procedure is defined in M13_externs.cpp
EXTERN OUTPUTSZ@4:NEAR   ; This procedure is defined in M13_externs.cpp
EXTERN strlen:NEAR       ; This procedure is part of the C standard library

EXTERN global_variable:DWORD    ; Sample global variable defined in M13_externs.cpp

PUBLIC SM_RUN            ; SM_RUN is externally visible to the linker

.const
        ; Constants corresponding to the command opcodes
        OPCODE_PUSH EQU 0
        OPCODE_ADD  EQU OPCODE_PUSH + 1
        ; ...       EQU OPCODE_PUSH + 2...

.data                   ; The data segment
        ; Table of procedure addresses invoked by the stack machine
        call_table DWORD OFFSET push_cmd
                   DWORD OFFSET add_cmd

.code                    ; Code segment begins

; Procedure for running the stack machine program
; Output: EAX is the status
SM_RUN  PROC

        ; Invoke procedures corresponding to particular opcodes
        mov   eax, OPCODE_PUSH
        call  call_table[ eax * 4 ]

        mov   eax, OPCODE_ADD
        call  call_table[ eax * 4 ]

        mov DWORD PTR [global_variable], 456;
        
        ret
SM_RUN  ENDP

; Sample procedure handling the PUSH command
.const
        SZ_PUSH_CMD BYTE "...push_cmd...", 13, 10, 0
.code
push_cmd PROC
        pushd OFFSET SZ_PUSH_CMD
        call  OUTPUTSZ@4 ; display text
        ret
push_cmd ENDP

; Sample procedure handling the ADD command
.const
        SZ_ADD_CMD BYTE "...add_cmd...", 13, 10, 0
.code
add_cmd PROC
        pushd OFFSET SZ_ADD_CMD
        call  OUTPUTSZ@4 ; display text
        ret
add_cmd ENDP

END