Download asmsim.jar and run it locally. History:
- Nov. 01, 2011: started to develop the AsmSim simulator.
- Apr. 01, 2012: used in the lecture of Computer Organization and Design.
- Oct. 24, 2012: converted from applet to application.
- Oct. 25, 2013: added "%p", "%i", "%u", and "%X" for printf() in C and System.out.format() in Java.
- Nov. 20, 2013: added a second window for showing Altera MIF codes with disassembled instruction codes.
- Nov. 26, 2013: added "subroutine_call.s", "pointer.s", and "root_nonrestoring.s" assembly program examples.
- Sep. 01, 2014: fixed shift bug.
- Nov. 18, 2014: "\011" ("\t") and "\012" ("\n") in .ascii were supported.
- Nov. 24, 2014: ".comm var, bytes, align" in .data was supported.
- Oct. 10, 2015: added "verilog" button; deleted "stop" button.
- Oct. 24, 2016: added "load" button for loading sample assembly programs; deleted "restart" button.
- Mar. 12, 2017: enlarged button size for Mac PCs.
- May 12, 2017: enabled "step" button although breakpoint is set.
- Sep. 13, 2022: supported "lw rt, %lo(label+imm)(rs)".
- Sep. 22, 2022: enabled local labels.
MIPS Assembly Program Examples
- hello.s
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/* * hello.s * Getting started, prints "Hello, World!" to STDOUT * printf() parameter in $4: the string address */ .text # code segment main: # program entry subu $sp, $sp, 64 # reserve stack space sw $ra, 60($sp) # save return address sw $fp, 56($sp) # save frame pointer move $fp, $sp # new frame pointer user_main: la $4, hello_msg # hello message address jal printf # print out message return_to_caller(os): # exit() move $sp, $fp # restore stack pointer lw $fp, 56($sp) # restore frame pointer lw $ra, 60($sp) # restore return address addu $sp, $sp, 64 # release stack space jr $ra # return to operating system .data # data segment hello_msg: # the string address .ascii "Hello, World!\n" # the string .end
- Factorial MIPS assembly program (recursive_factorial_mips.s)
- Tower of Hanoi MIPS assembly program (recursive_tower_of_hanoi_mips.s)
- Selection sort MIPS assembly program (selection_sort.s)
- Insertion sort MIPS assembly program (insertion_sort.s)
- Bubble sort MIPS assembly program (bubble_sort.s)
- Heap sort MIPS assembly program (heap_sort.s)
- Merge sort MIPS assembly program (merge_sort.s)
- Quicksort MIPS assembly program (quick_sort.s)
Functions the AsmSim Provides
- The basic assembly programs' assembling and simulation
- grammar checking
- translating to binary code
- single-step execution
- break-point setting
- showing the contents of the register file
- showing the contents of the data memory
- The basic input and output system function calls, like scanf() and printf() in C, or readLine() and System.out.print() in Java.
- Interrupt mechanism, like addKeyListener() and removeKeyListener() in Java, for handling the keyboard interrupt.
- Manipulating a standard VGA (640×480 pixels). The Direct Video RAM (VRAM) Access function allows user program to read/write a pixel (24-bit RGB pattern) from/to the VRAM. It is also possible for the user program to define the starting address of the VRAM.
- User defined font tables, 8x8 ASCII fonts and 16x16 Kanji fonts for examples.
- Graphics draw (draw‹object›() or fill‹object›() will be done in an off-screen buffer and paint() will display the image in the buffer on the graphics display by writing the image to the VRAM).
- Automatically generating Xilinx COE and Altera MIF memory initialization files.
- There are also some other functions, like "getrandom()" (get a random number), "gettimer()" (get the timer), "sleep()", "getcal()" and "getcals()" (get the calendar in integers and string, respectively).
Three Windows
- Main Window (for displaying instruction codes, register file contents, and data memory contents).
- Graphics Console (for command line input (STDIN), message output (STDOUT), and graphics drawing (VGA)).
- Program Edit Window (for editing your assembly language program).
The Contents in the Main Window
- The top part shows the data in the data memory in hexadecimal format. The most-left column shows the memory addresses.
- The program area is located in the center (left). From left to right, it shows (1) memory address (program counter), (2) the instruction encode in hexadecimal format, and (3) the source code of the user program.
- The right part shows the contents of the general-purpose registers plus registers $lo, $hi (for multiplication and division calculations), and $epc (for storing the return address before transferring the control to the exception handler).
- In the bottom of the window, there are 11 buttons which will be explained next.
The Buttons in the Main Window
- [edit]: opens the program edit window (in case it was closed).
- [step]: executes one instruction that is highlighted currently.
- [goto]: executes instructions until the break-point is reached. You can set the break-point by clicking on an instruction in the program area.
- [ascii]: displays the ascii of the selected contents in the data memory to the graphics console.
- [run]: executes user program.
- [quit]: quits from Debug Mode and enters Command Line Mode.
- [load]: loads sample assembly programs.
- [inst]: displays the encodes and formats of the mips instructions that were implemented currently in this tool.
- [xilinx]: generates Xilinx COE file (the contents of the file are displayed in a pop-up window).
- [altera]: generates Altera MIF file (the contents of the file are displayed in a pop-up window).
- [verilog]: generates Verilog HDL file (the contents of the file are displayed in a pop-up window).
Command Line and Debug Modes
In Command Line Mode (displaying "[asmsim]$ " in text console), you can type the command:
[asmsim]$ asmsim file ex., asmsim hello.s file: hello.s printf.s scanf.s getchar.s putchar.s sprintf.s getrandom.s gettimer.s getarrow.s getcal.s getcals.s linked_list.s sleep.s recursive.s malloc.s dfs.s bfs.s graphics.s key_event.s vram.s fonts.s kanji.s picture.s subroutine_call.s pointer.s root_nonrestoring.s You can edit your own program in the Program Editor window, and click Assemble button.
The basic operations of the assembly program examples which are provided with AsmSim are explained briefly as below.
- hello.s displays "Hello, World!" message on console window.
- printf.s prints out a word in three formats: "%d" (decimal), "%x" (hexadecimal), and "%s" (string).
- scanf.s reads an decimal integer, a hexadecimal integer, and a string from keyboard.
- getchar.s reads a character from keyboard.
- putchar.s prints out a character on console window.
- sprintf.s is similar to printf.s but it writes contents to a buffer first.
- getrandom.s gets a random number between 0 and 99.
- gettimer.s gets the value of the system timer.
- getarrow.s waits for pressing an arrow key.
- getcal.s gets the calendar information in integer format.
- getcals.s gets the calendar information in string format.
- linked_list.s shows the data structure of linked list.
- sleep.s sleeps for a moment.
- recursive.s calculates Fibonacci numbers recursively. Generally, recursive programs are difficult to understand, even they are written in high-level programming languages, like C and Java. By single-step instruction execution, we can track the stack and see how is the recursive program implemented.
- malloc.s allocates memory space.
- dfs.s implements the depth-first search (DFS) algorithm which is usually taught in the course of Data Structure and Algorithms. The graph used in the program is represented with the linked list.
- bfs.s implements the breadth-first search (BFS) algorithm.
- graphics.s draws graphics objects and string.
- key_event.s is a simple game program which demonstrates the keyboard interrupt. The game program uses four arrow keys to keep a randomly moved object in the center of the graphics window.
- vram.s writes true-color pixels into VRAM directly with sw instruction.
- fonts.s shows ASCII fonts using a user-defined font table.
- kanji.s displays some Japanese characters.
- picture.s shows a bit-mapped picture image on graphics window.
- subroutine_call.s shows how the function call in C is implemented.
- pointer.s shows how the pointer in C is implemented.
- root_nonrestoring.s implements a non-restoring square root algorithm.
The "asmsim template.s" command is executed automatically once this page is opened, and the asmsim enters to debug mode. The text console is a simple bash terminal that can accept only one command: "asmsim" with a parameter: "program_name".
In Debug Mode (displaying "debug> " in text console), you can type one of the commands:
step, run, restart, ascii 0x‹address›, and quit
All most these commands can be also executed by clicking the corresponding buttons in the main window.
The Use of the VGA
- The user programs have full control of the accesses to the VGA. You can use "lw" or "sw" instruction to read from or write to the VRAM directly. The default mode is that once a pixel is written to VRAM, it appears on VGA immediately. But this mode will takes long times when a large number of pixels need to be written to VRAM continuously. Therefore, we provide a system call, namely "refresh_vga_manu()", to inhibit the automatic display. Under this mode, the VGA image is updated only when the user program executes the system call of the "paint()". See the example of "vram.s". The "refresh_vga_auto()" resumes the default mode.
- This simulator supports a user-defined Font Table. See the example "fonts.s" program in which a font table for ASCII characters (8x8 pixels) is given in the user data area. Another example is "kanji.s" that displays Japanese characters with 16x16 fonts.
- You can implement a driver for manipulating the VGA. For example, the system call of the "printf()" displays messages on the text console, you can write a driver to let such as "vga_printf()" display massages on the VGA. Another example is "vga_scanf()" that must deal with the "Backspace" and "Enter" keys. Challenge it! You are also encouraged to use the VGA to develop games, such as "Othello" and "2D/3D Tetris". Have a fun with the "Assembly Language Programming"!
System Calls
- getchar() gets a character from STDIN. The ASCII of the character will be in register $2 after the invocation.
- putchar() puts a character to STDOUT. $4 holds the ASCII of the character which will be outputted.
- scanf() reads an input from STDIN. $4 holds the address of a string which can be "%d", "%x", or "%s", indicating the format of the input data. $5 holds the memory address where the inputted value will be stored.
- printf() writes output(s) to STDOUT. $4 holds the address of a string which may contain multiple directives of "%d", "%x", and/or "%s". The multiple output data corresponding to the directives are putted into $5, $6, $7, stack[16($sp)], stack[20($sp)], ..., in sequence.
- sprintf() writes output(s) to a buffer. $4 holds the address of the buffer. $5 holds the address of a string which may contain multiple directives of "%d", "%x", and/or "%s". The multiple output data corresponding to the directives are putted into $6, $7, stack[16($sp)], stack[20($sp)], ..., in sequence.
- malloc() allocates a block of memory. $4 holds the block size in bytes. The starting address of the allocated memory block will be in $2 after the invocation.
- gettimer() gets the system timer in ms (milli-seconds). The timer will be in $2 after the invocation.
- getrandom() gets a random integer number r with 0 ≤ r < n, where n is given in $4. The random number will be in $2 after the invocation.
- getarrow() gets an arrow key's information. The information of the pressed arrow key will be in $2 after the invocation: 0x8000 for Up key; 0x8100 for Left key; 0x8200 for Down key; and 0x8300 for Right key. We also defined 0xff00 for Escape key.
- getcal() gets the calendar in integers. $4 holds the starting address of an integer array where the Month, Date, Year, Day, Hour, Minute, and Second will be stored in sequence.
- getcals() gets the calendar in string. $4 holds the address of the string. The format of the string is "Month Date Year Day Hour:Minute:Secons".
- sleep() suspends execution for an interval of time. $4 holds the interval in ms.
- key_event_ena() enables keyboard interrupt. Pressing a key will cause a transfer of control to an pre-defined exception handler. No parameters are required.
- key_event_dis() disables keyboard interrupt. No parameters are required.
- drawline() draws a color line on an off-screen buffer. $4 holds the starting address of an integer buffer where the line color, x1, y1, x2, and y2 are stored in sequence. The line will be drawn from (x1,y1) to (x2,y2). The line color is defined by a 24-bit integer: 8 bits for each of Red, Green, and Blue, from MSB to LSB.
- drawoval() draws a color oval which fits into a specified rectangle on an off-screen buffer. $4 holds the starting address of an integer buffer where the line color, x, y, w, and h are stored in sequence. (x,y) is the up-left coordinate of the rectangle; w and h are the width and height of the rectangle, respectively. The color is specified by a 24-bit integer.
- drawrect() draws a color rectangle on an off-screen buffer. $4 holds the starting address of an integer buffer where the line color, x, y, w, and h are stored in sequence. (x,y) is the up-left coordinate of the rectangle; w and h are the width and height of the rectangle, respectively. The color is specified by a 24-bit integer.
- drawrect3d() is similar to drawrect() but the rectangle appears to be raised above the surface (3D). The parameters are the same as drawrect().
- drawstring() draws specified text at specified location on an off-screen buffer. $4 holds the starting address of a buffer where the text color, x, y, font information, and the text are stored in sequence. (x,y) is the coordinate where the text will be drawn; the font information is given by a 24-bit integer that specifies font name (8 bits), font type (8 bits), and font size (8 bits). The supported font names in this simulator include "Times New Roman" (0), "Arial" (1), "Courier New" (2), and "Coronna MT" (3). The supported font types are "Plain" (0), "Bold" (1), and "Italic" (2).
- filloval() fills a color oval on an off-screen buffer. The parameters are the same as drawoval().
- fillrect() fills a color rectangle on an off-screen buffer. The parameters are the same as drawrect().
- fillrect3d() fills a color 3D rectangle on an off-screen buffer. The parameters are the same as drawrect3d().
- refresh_vga_auto() enables the automatic VRAM display.
- refresh_vga_manu() inhibits the automatic VRAM display, the VGA image is updated only when the user program executes the system call of the "paint()".
- paint() The drawing objects and filling objects described above are done in an off-screen buffer. The paint() shows the image in the off-screen buffer on the VGA. No parameters are required.
Screen Shots
Rivasm - A RISC-V RV32IM Simulator
Rivasm - A RISC-V RV32IM Assembly Program Assembler and Simulator