ldc 3             // a
                    ldc 4             // a, b
                    lds -1            // a, b, a
                    lds -1            // a, b, a, b
                    mul               // a, b, a*b
                    ldc 4             // a, b, a*b, 4
                    sub               // a, b, a*b-4
                    sts -2            // a*b-4, b
                
                          ldc 3             // a
                          ldc 4             // a, b
                          lds -1            // a, b, a
                          lds -1            // a, b, a, b
                          mul               // a, b, a*b
                          ldc 4             // a, b, a*b, 4
                          sub               // a, b, a*b-4
                          sts -2            // a*b-4, b
                          ne
                          brt NE            // a*b-4, b
                          ldc 0             // a*b-4, b, 0
                          str RR            // a*b-4, b, RR=0
                          bra DONE          // a*b-4, b, RR=0
                    NE:   ldc 1             // a*b-4, b, 1
                          str RR            // a*b-4, b, RR=1
                    DONE: halt 
                
                               ldc 3             // 3
                               ldc 4             // 3, 4
                               bsr SUMSQUARE     // 3, 4, PC
                               ajs -2            // -empty-stack-
                               ldr RR            // SUMSQUARE: our answer 25
                               bra DONE
                    SUMSQUARE: link 1            // 3, 4, PC, MP, x
                               ldl -3            // 3, 4, PC, MP, x, 3, 3
                               ldl -3            // 3, 4, PC, MP, x, b, a
                               mul               // 3, 4, PC, MP, x, 9
                               ldl -2            // 3, 4, PC, MP, x, 9, 4
                               ldl -2            // 3, 4, PC, MP, x, 9, 4, 4
                               mul               // 3, 4, PC, MP, x, 9, 16
                               add               // 3, 4, PC, MP, x, 25
                               stl 1             // 3, 4, PC, MP, 25
                               ldl 1             // 3, 4, PC, MP, 25, 25
                               str RR            // 3, 4, PC, MP, 25  RR=25
                               unlink 1          // 3, 4, PC
                               ret               // 3, 4
                    DONE:
                
                              bra MAIN             //  0:
                    FAC:      link                 //  1: N, 21, MP
                              ldl -2               //  2: N, 21, MP, N
                              LDC 1                //  3: N, 21, MP, N, 1
                              le                   //  4: N, 21, MP, true/false
                              brt FAC-BASE         //  5: N, 21, MP
                              ldl -2               //  6: N, 21, MP, N
                              ldl -2               //  7: N, 21, MP, N, N
                              LDC 1                //  8: N, 21, MP, N, N, 1
                              sub                  //  9: N, 21, MP, N, N - 1
                              bsr FAC              // 10: N, 21, MP, N, N - 1, 2
                              ldr RR               // 11: 
                              mul                  // 12: N * factorial (N - 1)
                              bra FAC-DONE         // 13:
                    FAC-BASE: LDC 1                // 14: N, 21, MP, 1
                    FAC-DONE: str RR               // 15: N, 21, MP   RR=1
                              unlink               // 16: N, 21
                              sts -1               // 17: 21
                              ret                  // 18:
                    MAIN:     LDC 20               // 19: N = 20
                              bsr FAC              // 20: N, 21  FAC ( 20 )
                              bra DONE
                    DONE:     halt
                
                              bra MAIN
                    FAC:      link 1               // fac( int n )
                              LDC 1                // int res = 1 
                              stl 1
                    FACTEST:  ldl -2               // while ( n > 1 )
                              LDC 1
                              gt
                              brf FACEND
                              ldl -2               // res = res * n 
                              ldl 1
                              mul
                              stl 1
                              ldl -2               // n = n - 1
                              LDC 1
                              sub
                              stl -2
                              bra FACTEST
                    FACEND:   ldl 1                // return( res )
                              str RR
                              unlink
                              sts -1
                              ret
                    MAIN:     LDC 6
                              bsr FAC              // fac( 6 )
                              halt
                

SJSSM is superceeded by SJSSM2!

SJSSM: Simple JavaScript Stack Machine

About SJSSM

This is the Simple JavaScript Stack Machine. It can be programmed to execute a simple set of assembly-like instructions on a simulated stack machine.

I recommend using the JavaScript console that is part of WebKit's Web Inspector in either Google Chrome or Safari.

Have fun!

Usage

The follwing is a short overview of how the app can be used from the JavaScript console in your browser.

Obtaining a SJSSM Instance

An SJSSM object has to be instantiated to start using the machine:

> machine = new SJSSM;
< Object
            

Programming the Machine

Code can be loaded directly into the machine by using the program() method and passing your source as an argument. Check the instruction set reference for documentation on the available instructions.

To get started quickly, there are some predefined code blocks available, that can be used to program the machine. These can be loaded from the source of this page using jQuery, like this:

> machine.program($('#sjssm > #simplemath').text());
< undefined
            

The example above uses simple categorization under the #sjssm collection.

The available example code blocks in #sjssm are:

You can, of course, easily add your own programs to this page. Just view the page source. The programs are at the beginning of the body-tag. If you want to, you can create your own categories.

You can find an overview of all categories and programs in the program index.

Starting the Machine

The machine can be started with the following statement, which makes it run the code that is currently loaded:

> machine.run();
< ...
< undefined
            

Note that the run() method does not return anything. In fact, running the machine does not have any predefined result or even a purpose. If your code does do something useful, you probably want to get some data from a register or from the stack, in which case you can use these inspection statements.

Stepping the Machine

Instead of starting the machine and letting it execute a program until it thinks it is done, the step() method can be used to let the machine execute a fixed number of steps and then wait. This can be useful when debugging and inspection of the machine is needed while a program is still executing. The machine can be stepped with the following statement:

> machine.step(2);
< true
            

The step() methow will return either true or false, indicating the success or failure of the last step. When a step fails, additional information will be printed to the console.

Resetting the Machine

The machine can be resetted with the following statement, which sets all its registers to the startup values, empties the stack and clears any currently loaded code:

> machine.reset();
< undefined
            

Inspecting the Machine

The machine can reveal several internal properties that are interresting for the user, such as its registers, the stack and the loaded code:

> machine.getRegisters();
< Object
> machine.getRegisters().RR;
< 42
> machine.getStack();
< [3, 5, ...]
> machine.getCode();
< [Object, Object, Object, ...]
            

Program Index

This is a full index of all predefined programs found in the page source. Click on a program's name to expand the code listing.

Documentation

This section documents the machine's registers, it's instruction set and some important concepts used in the machine implementation.

Registers

The SJSSM is simple and has a minimal number of registers. The registers currently implemented are the minimum required for a functional stack machine that supports the current instruction set.

Register Name Description
Program Counter PC Stores the program counter, which points to the next executed instruction in the program loaded into the machine.
Stack Pointer SP Stores the stack pointer, which points to the top of the stack.
Mark Pointer MP Stores the mark pointer, which points to a previously marked position in the stack.
Return Register RR Stores arbitrary values, which are, for example, returned from subroutines or otherwise put there by the program.
Interrupt Register IR This register is not used currently.

Using Labels

Labels are used to mark lines in the machine code. They can be used when jumping to a specific location in the code (branching). Branching is used in flow control and for executing subroutines.

The main purpose of using labels is to eliminate the need to use static numeric values to reference positions in a program's code, making code easier to read, edit and understand.

See the instruction set reference for instructions that use labels.

Instruction Set

The following table gives a complete overview of the instruction set available in SJSSM.

All the instructions have either 1 parameter or none at all. Instructions that take registers as an argument should use one of the registers from the register reference.

Machine control

Instruction Op Param Description Example
Halt machine halt Halt the machine to make it stop executing code. halt

Stack operations

Instruction Op Param Description Example
Load constant ldc number Push a numeric value onto the stack. ldc 42
Load from register ldr register Push the value in the specified register onto the stack. ldd RR
Load from stack (SP) lds offset Push the value at the position in the stack indicated by the specified offset, relative to the stack pointer, onto the stack. lds -1
Load from stack (MP) ldl offset Push the value at the position in the stack indicated by the specified offset, relative to the mark pointer, onto the stack. ldl -2
Store in register str register Pop the top most value from the stack and store it in the specified register. str RR
Store in stack (SP) sts offset Pop the top most value from the stack and store it in the stack at the position specified by the offset, relative to the stack pointer. sts -3
Store in stack (MP) stl offset Pop the top most value from the stack and store it in the stack at the position specified by the offset, relative to the mark pointer. stl -2
Adjust stack ajs adjustment Given a positive or negative value specified by the adjustment, grow or shrink the stack, by pushing empty values or popping existing values onto or from the stack, respectively. ajs -2

Arithmetic operations

Instruction Op Param Description Example
Addition add Pop the top two values from the stack, add them, and push the result back. add
Subtraction sub Pop the top two values from the stack, subtract them, and push the result back. sub
Multiplication mul Pop the top two values from the stack, multiply them, and push the result back. mul
Division div Pop the top two values from the stack, divide them, and push the result back. div
Modulation mod Pop the top two values from the stack, take the modulo, and push it back. mod
Negation neg Pop the top value from the stack, negate it, and push the result back. neg

Boolean operations

Instruction Op Param Description Example
Equals eq Pop the top two values from the stack, compare them, and push a true value back onto the stack if they're equal, else push a false value. eq
Not equals ne Pop the top two values from the stack, compare them, and push a true value back onto the stack if they're not equal, else push a false value. ne
Greater then gt Pop the top two values from the stack, compare them, and push a true value back onto the stack if the first is greater then the second, else push a false value. gt
Less then lt Pop the top two values from the stack, compare them, and push a true value back onto the stack if the first is less then the second, else push a false value. lt
Greater or equals ge Pop the top two values from the stack, compare them, and push a true value back onto the stack if the first is greater then or equal to the second, else push a false value. ge
Less or equals le Pop the top two values from the stack, compare them, and push a true value back onto the stack if the first is less then or equal to the second, else push a false value. le

Flow Control operations

Instruction Op Param Description Example
Branch if true brt label Pop the top most value from the stack, check if it's true. If so jump to the position specified by label. brt DOTRUE
Branch if false brf label Pop the top most value from the stack, check if it's false. If so jump to the position specified by label. brf DOFALSE
Branch always bra label Immediately jump to the position specified by label. brf DOALWAYS
Branch to subroutine bsr label Push the current value from the PC-register onto the stack, and then jump to the position specified by label. bsr SUBRTN
Return ret Pop the top most value of the stack, and 'return' to it, by jumping to the position indicated by that value. ret

Subroutine operations

Instruction Op Param Description Example
Link subroutine link number Links a subroutine, by:
  • Pushing the current value in the MP-register, the mark pointer, onto the stack
  • Storing the current value in the SP-register, the stack pointer, into the MP-register
  • Pushing number empty values onto the stack, to use for local variables in the subroutine.
link 2
Unlink subroutine link number Unlinks a subroutine, by:
  • Popping number values off the stack.
  • Popping the top value off the stack, the saved mark pointer, and storing it in the MP-register
unlink 2