Saturday, April 18, 2020

MIPS file manipulation and runtime exception tests

This is MIPS assembler code that demonstrates file manipulation (open, close read, write), read from and write to memory. EzMIPS handles all cases with care and raises Runtime Exception when appropriate. EzMIPS should never crash or hang.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# -------- file manipulation and runtime exception tests --------- #

.data

wTest:         .word   0x12345678
szValidFile:   .asciiz "c:/test.txt"
szInvalidFile: .asciiz "c:\\Users\\Antonis.ANTONIS-PC\\Desktop\\invalid.txt"
szSpace:       .space  2000

.text

main:

# ........................... Open file .......................... #
    
    la $a0, szValidFile    # if $a0 = address of valid null-terminated filename string
                           # $v0 = valid FILE pointer after the following syscall

   #la $a0, szInvalidFile  # if $a0 = address of invalid null-terminated filename string
                           # $v0 = -1 after the following syscall

    li $a1, 0              # $a1 = flag = 0 -> "r"
    li $v0, 13
    syscall
    
    move $a3, $v0          # Keep file descriptor safe!

# ................. read file text and put it in buffer .......... #

    move $a0, $v0       # if $a0 = valid file descriptor
                        # $v0 = number of bytes read after the following syscall
                        # if $a0 = invalid file descriptor, $v0 = -1 after the following syscall

    li $v0, 14          # read from file
    la $a1, szSpace     # adrress of buffer
    li $a2, 200         # number of bytes to be read
    syscall

# .......................... close file .......................... #

    # $a0 = file descriptor
    move $a0, $a3     # if $a0 = valid file descriptor -> $v0 = 0 after the following syscall
                      # if $a0 = invalid file descriptor -> $v0 = -1 after the following syscall
    li $v0, 0x10      # = 16
    syscall

# ........................... Open file .......................... #

    la $a0, szInvalidFile
    li $a1, 1              # $a1 = flag = 1 -> "w"
    li $v0, 13
    syscall
    move $a3, $v0          # Keep file descriptor safe!

# ......................... Write to file ........................ #

    move $a0, $v0         # $a0 = file descriptor
    la $a1, szSpace       # $a1 = address of output buffer
    li $a2, 100           # $a2 = number of characters to write
    li $v0, 15
    syscall
    # return: $v0 contains number of characters written (-1 if error)

# .......................... close file .......................... #

    # $a0 = file descriptor
    move $a0, $a3     # if $a0 = valid file descriptor -> $v0 = 0 after the following syscall
                      # if $a0 = invalid file descriptor -> $v0 = -1 after the following syscall

    li $v0, 0x10      # = 16
    syscall

# ............................. jr test .......................... #

    #jr $ra

# ............................ swr test .......................... #
    
    #la $t1, szValidFile
    #la $t1, wTest
    #addi $t1, $t1, -1
    swr $a0, 3($t1)
    swr $a1, 2($t1)
    swr $a2, 1($t1)
    swr $a3, 0($t1)

# ............................ swl test .......................... #
    
    #la $t1, szValidFile
    #la $t1, wTest
    #addi $t1, $t1, -1
    swl $a0, 0($t1)
    swl $a1, 1($t1)
    swl $a2, 2($t1)
    swl $a3, 3($t1)

# ............................ lwr test .......................... #
    
    la $t1, szValidFile
    #la $t1, wTest
    addi $t1, $t1, -1
    lwr $a0, 0($t1)
    lwr $a1, 1($t1)
    lwr $a2, 2($t1)
    lwr $a3, 3($t1)

# ........................... lhu test ........................... #
    
    #la $t1, szValidFile
    #la $t1, wTest
    #addi $t1, $t1, 1
    lhu $a0, 0($t1)
    lhu $a2, 2($t1)

# .......................... lbu test ............................ #
    
    #la $t1, szValidFile
    #la $t1, wTest
    #addi $t1, $t1, -1
    lbu $a0, 0($t1)
    lbu $a1, 1($t1)
    lbu $a2, 2($t1)
    lbu $a3, 3($t1)

# ............................ lw test ........................... #
    
    #la $t1, szValidFile
    #la $t1, wTest
    #addi $t1, $t1, -1
    lw $a0, 0($t1)
    lw $a1, 1($t1)
    lw $a2, 2($t1)
    lw $a3, 3($t1)


# ............................ lwl test .......................... #
    
    #la $t1, szValidFile
    #la $t1, wTest
    #addi $t1, $t1, -1
    lwl $a0, 0($t1)
    lwl $a1, 1($t1)
    lwl $a2, 2($t1)
    lwl $a3, 3($t1)

# ............................ lh test ........................... #
    
    #la $t1, szValidFile
    #la $t1, wTest
    lh $a0, 0($t1)

# ............................ lb test ........................... #
    
    #la $t1, szValidFile
    #la $t1, wTest
    lb $a0, 0($t1)

# ......................... Write to file ........................ #
    
    li $a0, 0              # $a0 = file descriptor
    li $a1, 0              # $a1 = address of output buffer
    la $a1, szValidFile    # $a1 = address of output buffer
    li $a2, 10             # $a2 = number of characters to write
    li $v0, 15
    syscall
    # return: $v0 contains number of characters written (-1 if error)

# .......................... Open file ........................... #
    
    # Runtime exception at 0x--------: cannot read directly from this address <0x00000000>
    li $a0, 0    # $a0 = address of null-terminated filename string
    li $a1, 0    # $a1 = flag = 0 -> "r"
    li $v0, 13
    syscall

# ........................ read integer .......................... #
    
    # Runtime exception at 0x--------: invalid integer input (syscall 5)
    # if invalid integer given by the user
    li $v0, 5
    syscall

# ....................... print string ........................... #
    
    # Runtime exception at 0x--------: cannot read directly from this address <0x00000000>
    li $a0, 0
    li $v0, 4
    syscall

# ................................................................ #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Saturday, April 11, 2020

MIPS power of x^n calculation

This is MIPS assembler code that, given a base number (x) and an exponent (n), it calculates the power of xn. The code is fully commented.

Launch EzMIPSthe MIPS assembler simulator, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# ----------------- power(x^n) function in MIPS ------------------ #

# $t0 = x   (base)
# $t1 = n   (exponent - must be greater than or equal to 0)
# $t2 = x^n (result)

# ---------------------------------------------------------------- #

.data

szEnterBase:     .asciiz "Enter base (x)     :"
szEnterExponent: .asciiz "Enter exponent (n) :"    # greater or equal to 0
szResult:        .asciiz "Result: "

# ---------------------------------------------------------------- #

.text

main:

# ................ print "Enter base (x): " ...................... #

    li $v0, 4                         # print string
    la $a0, szEnterBase               # load string address
    syscall                           # print it!

# ................. read base from user .......................... #

    li $v0, 5                         # read integer
    syscall                           # read it!
    move $t0, $v0                     # keep base in $t0

# ................ print "Enter exponent (n): " .................. #
exponent:

    li $v0, 4                         # print string
    la $a0, szEnterExponent           # load string address
    syscall                           # print it!

# ................. read exponent from user ...................... #

    li $v0, 5                         # read integer
    syscall                           # read it!
    blt $v0, $zero, exponent          # exponents greater or equal to 0
    move $t1, $v0                     # keep exponent in $t1

# ..................... $t2 = power($t0^$t1) ..................... #

    li $t2, 1                         # $t2 = result = 1
    beq $t1, $zero, exit_pow          # if (n==0)

while:

    mul $t2, $t2, $t0                 # x = x*x
    addi $t1, $t1, -1                 # n--
    bne $t1, $zero, while             # while (n>0)

exit_pow:

# ...................... print "Result: " ........................ #

    li $v0, 4                         # print string
    la $a0, szResult                  # load string address
    syscall                           # print it!

# ..................... print integer result ..................... #
    
    li $v0, 1                         # print integer
    move $a0, $t2                     # integer to print must be in $a0
    syscall                           # print it!

# ....................... exit program ........................... #

    li $v0, 10                        # return to OS
    syscall                           # do it!

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Friday, April 10, 2020

MIPS multiplication, power of two, addition

This is sample MIPS assembler code demonstrating multiplication, power of two and addition by EzMIPS, the MIPS assembler simulator. The code is by no means optimized, but written for beginners.

Launch EzMIPS, copy the following, fully commented, MIPS code and paste it into EzMIPS. Assemble, Run.

# ------- MIPS multiplication, power of two, addition ------- #

.data

szPrompt: .asciiz "Enter value of x : "
szResult: .asciiz "2 * (x^2 + x*3) = "

# ----------------------------------------------------------- #

.text

main:

# .............. print string "Enter value of x : " ......... #

    li $v0, 4          # print string
    la $a0, szPrompt   # load address off string to be printed
    syscall            # print it!

# ..................... read integer from user .............. #

    li $v0, 5           # read integer
    syscall

    move $s0, $v0       # integer read is in $v0
                        # save the integer in $s0 for later use

# ......... Calculate x^2 + x*3 and store it in $t0 ......... #

    mul $t0, $s0, $s0   # $t0 = x^2

    addi $t2, $zero, 3  # $t2 = 3
    mul $t1, $s0, $t2   # $t1 = x * 3

    add $t0, $t0, $t1   # $t0 = $t0 + $t1 = x^2 + x*3

    # final calculation!
    add $t0, $t0, $t0   # $t0 = $t0 + $t0
                        # $t0 = x^2 + x*3 + x^2 + x*3
                        # $t0 = 2 * (x^2 + x*3) 

# .............. print string "2 * (x^2 + x*3) = " .......... #

    li $v0, 4          # print string
    la $a0, szResult   # load address off string to be printed
    syscall            # print it!
    
# ................... print integer result .................. #

    li $v0, 1          # print integer
    move $a0, $t0      # number to print must be in $a0
    syscall            # print it!

# ........................................................... #
    
    # exit program
    li $v0, 10
    syscall

# ----------------------------------------------------------- #


Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Tuesday, April 7, 2020

MIPS div and divu instructions

This is sample MIPS assembler code demonstrating the correct operation of the div and divu instructions by EzMIPS, the MIPS assembler editor & simulator. The code is fully commented.

Launch EzMIPS, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# --------------- div, divu division instructions ---------------- #
.data

szMenu:         .ascii  "Choose division type\n"
                .ascii  "--------------------------\n"
                .ascii  "1. Use div instruction\n"
                .ascii  "2. Use divu instruction\n"
                .asciiz "3. Exit\n"

.text

main:

# ................................................................ #
# Comment any 2 lines for $t5 and any 2 lines for $t6 and check result of
# div and divu instructions. Any combination should give appropriate results! 

    li $t5, 0xffffffff
#   li $t5, 0x7fffffff
#   li $t5, 0x80000000

#   li $t6, 0xffffffff
#   li $t6, 0x7fffffff
    li $t6, 0x80000000

# ................................................................ #
    
    li $t1, 1
    li $t2, 2
    li $t3, 3

# ................................................................ #

print_menu:

    # print menu
    li $v0, 4
    la $a0, szMenu
    syscall

# ................................................................ #
    
    # get user input
    li $v0, 5
    syscall
    # $v0 holds user input

    beq $v0, $t3, exit
    beq $v0, $t2, use_divu
    bne $v0, $t1, print_menu

# ................................................................ #

use_div:
    div $t5, $t6
    j print_menu         # Display menu again

# ................................................................ #

use_divu:
    divu $t5, $t6
    j print_menu         # Display menu again

# ................................................................ #

exit:

    li $v0, 10
    syscall

# ---------------------------------------------------------------- #


Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

MIPS mult, multu and mul instructions

This is sample MIPS assembler code demonstrating the correct operation of the mult, multu and mul instructions by EzMIPS, the MIPS assembler editor & simulator. The code is fully commented.

Launch EzMIPS, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# -------------- mult, multu, mul multiplication ----------------- #

.data

szMenu:         .ascii  "Choose multiplication type\n"
                .ascii  "--------------------------\n"
                .ascii  "1. Use mult instruction\n"
                .ascii  "2. Use multu instruction\n"
                .ascii  "3. Use mul instruction\n"
                .asciiz "4. Exit\n"

.text

main:

# ................................................................ #
# Comment any 2 lines for $t5 and any 2 lines for $t6 and check result of
# mult, multu and mul. Any combination should give appropriate results!

    li $t5, 0xffffffff
    li $t5, 0x7fffffff
    li $t5, 0x80000000

    li $t6, 0xffffffff
    li $t6, 0x7fffffff
    li $t6, 0x80000000

# ................................................................ #
    
    li $t1, 1
    li $t2, 2
    li $t3, 3
    li $t4, 4

# ................................................................ #

print_menu:

    # print menu
    li $v0, 4
    la $a0, szMenu
    syscall

# ................................................................ #
    
    # get user input
    li $v0, 5
    syscall
    # $v0 holds user input

    beq $v0, $t4, exit
    beq $v0, $t3, use_mul
    beq $v0, $t2, use_multu
    bne $v0, $t1, print_menu

# ................................................................ #

use_mult:
    mult $t5, $t6
    j print_menu         # Display menu again

# ................................................................ #

use_multu:
    multu $t5, $t6
    j print_menu         # Display menu again

# ................................................................ #

use_mul:
    mul $t0, $t5, $t6
    j print_menu         # Display menu again

# ................................................................ #

exit:

    li $v0, 10
    syscall

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

Monday, April 6, 2020

MIPS register - register subtraction overflow (sub)

This is sample MIPS assembler code demonstrating register - register subtraction overflow. It detects subtraction overflow using MIPS hardware overflow simulation supported by EzMIPS, the MIPS assembler editor & simulator. The code is fully commented.

Launch EzMIPS, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# ---------- Register - register subtraction overflow ------------ #

.data

szMenu:         .ascii  "Detect register - register subtraction overflow?\n"
                .ascii  "------------------------------------------------\n"
                .ascii  "1. Runtime exception: arithmetic overflow\n"
                .asciiz "2. Exit\n"

.text

main:

# ............... Test one for subtraction overflow .............. #


    li $t4, 0x80000000    # -2147483648
    li $t5, 0x01          # 1
    
    # OVERFLOW!!!
    # 0x80000000  - 0x01  = 0x7FFFFFFF
    # -2147483648 - 1     = 2147483647         <- OVERFLOW

# ........ Uncomment for test two for subtraction overflow ....... #

    #li $t4, 0xfffffffe    # -2
    #li $t5, 0x7fffffff    # 2147483647

    # OVERFLOW!!!
    # 0xfffffffe  - 0x7fffffff = 0x7fffffff
    # -2          - 2147483647 = 2147483647     <- OVERFLOW

# ................................................................ #
    
    li $t1, 1
    li $t2, 2

# ................................................................ #

print_menu:

    # print menu
    li $v0, 4
    la $a0, szMenu
    syscall

# ................................................................ #
    
    # get user input
    li $v0, 5
    syscall
    # $v0 holds user input

    beq $v0, $t2, exit
    bne $v0, $t1, print_menu

# ................................................................ #
    
    # Runtime exception: arithmetic overflow
    sub $t0, $t4, $t5   # subtraction with Overflow Runtime exception
    j print_menu        # if no runtime exception occured, print menu

# ................................................................ #

exit:

    li $v0, 10
    syscall

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis

MIPS register - immediate addition overflow (addi)

This is sample MIPS assembler code demonstrating register - immediate addition (addi instruction) overflow. It detects addition overflow using MIPS hardware overflow simulation supported by EzMIPS, the MIPS assembler editor & simulator. The code is fully commented.

Launch EzMIPS, copy the following MIPS code and paste it into EzMIPS. Assemble, Run.

# -------------- Register - Immediate addition overflow ----------- #

.data

szMenu:         .ascii  "Detect register - immediate addition overflow?\n"
                .ascii  "----------------------------------------------\n"
                .ascii  "1. Runtime exception: arithmetic overflow\n"
                .asciiz "2. Exit\n"

.text

main:

# ........ Test the addition overflow of 2 positive numbers ...... #

    li $t4, 0x7fffffff      # = 2147483647
    
    # OVERFLOW!!!
    # 0x7fffffff + 0x00000001 = 0x80000000
    # 2147483647 + 1          = -2147483648

# ... Uncomment to test addition overflow of 2 negative numbers .. #

    #li $t4, 0x80000000     # = -2147483648

    # OVERFLOW!!!
    # 0x80000000  + 0xffffffff = 0x7fffffff
    # -2147483648 + -1         = 2147483647

# ................................................................ #
    
    li $t1, 1
    li $t2, 2

# ................................................................ #

print_menu:

    # print menu
    li $v0, 4
    la $a0, szMenu
    syscall

# ................................................................ #
    
    # get user input
    li $v0, 5
    syscall
    # $v0 holds user input

    beq $v0, $t2, exit
    bne $v0, $t1, print_menu

# ................................................................ #
    
    # Runtime exception: arithmetic overflow of two positive numbers
    # .................................... #
    addi $t0, $t4, 0x1      # addition with Overflow Runtime exception

    # Uncomment the following line to test #
    # .................................... #
    # Runtime exception: arithmetic overflow of two NEGATIVE numbers 
    #addi $t0, $t4, 0xffff   # addition with Overflow Runtime exception

    j print_menu            # if no runtime exception occured, print menu

# ................................................................ #

exit:

    li $v0, 10
    syscall

# ---------------------------------------------------------------- #

Please let me know of any suggestions or bugs regarding the code above.

Regards,

Antonis