exercism / mips

Exercism exercises in MIPS Assembly.
https://exercism.org/tracks/mips
MIT License
22 stars 29 forks source link

Building a training set of tags for mips #180

Closed iHiD closed 11 months ago

iHiD commented 1 year ago

Hello lovely maintainers :wave:

We've recently added "tags" to student's solutions. These express the constructs, paradigms and techniques that a solution uses. We are going to be using these tags for lots of things including filtering, pointing a student to alternative approaches, and much more.

In order to do this, we've built out a full AST-based tagger in C#, which has allowed us to do things like detect recursion or bit shifting. We've set things up so other tracks can do the same for their languages, but its a lot of work, and we've determined that actually it may be unnecessary. Instead we think that we can use machine learning to achieve tagging with good enough results. We've fine-tuned a model that can determine the correct tags for C# from the examples with a high success rate. It's also doing reasonably well in an untrained state for other languages. We think that with only a few examples per language, we can potentially get some quite good results, and that we can then refine things further as we go.

I released a new video on the Insiders page that talks through this in more detail.

We're going to be adding a fully-fledged UI in the coming weeks that allow maintainers and mentors to tag solutions and create training sets for the neural networks, but to start with, we're hoping you would be willing to manually tag 20 solutions for this track. In this post we'll add 20 comments, each with a student's solution, and the tags our model has generated. Your mission (should you choose to accept it) is to edit the tags on each issue, removing any incorrect ones, and add any that are missing. In order to build one model that performs well across languages, it's best if you stick as closely as possible to the C# tags as you can. Those are listed here. If you want to add extra tags, that's totally fine, but please don't arbitrarily reword existing tags, even if you don't like what Erik's chosen, as it'll just make it less likely that your language gets the correct tags assigned by the neural network.


To summarise - there are two paths forward for this issue:

  1. You're up for helping: Add a comment saying you're up for helping. Update the tags some time in the next few days. Add a comment when you're done. We'll then add them to our training set and move forward.
  2. You not up for helping: No problem! Just please add a comment letting us know :)

If you tell us you're not able/wanting to help or there's no comment added, we'll automatically crowd-source this in a week or so.

Finally, if you have questions or want to discuss things, it would be best done on the forum, so the knowledge can be shared across all maintainers in all tracks.

Thanks for your help! :blue_heart:


Note: Meta discussion on the forum

iHiD commented 1 year ago

Exercise: binary

Code

#
# Test binary_convert with some examples
#
# s0 - num of tests left to run
# s1 - address of input word
# s2 - address of expected output word
# s3 - char byte
# s4 - output word
#
# binary_convert must:
# - be named binary_convert and declared as global
# - read input address of string from a0
# - follow the convention of using the t0-9 registers for temporary storage
# - (if it uses s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning)
# - write integer result to v0

.data

# number of test cases
n: .word 9
# input values (null terminated) & expected output values (word sized ints)
ins:  .asciiz "0", "1", "10", "11", "100", "1001", "11010", "10001101000", "000011111"
outs: .word     0,   1,   2,     3,    4,       9,      26,          1128,          31

failmsg: .asciiz "failed for test input: "
okmsg: .asciiz "all tests passed"

.text

runner:
        lw      $s0, n
        la      $s1, ins
        la      $s2, outs

run_test:
        move    $a0, $s1                # move address of input str to a0
        jal     binary_convert          # call subroutine under test
        move    $v1, $v0                # move return value in v0 to v1 because we need v0 for syscall

        lw      $s4, 0($s2)             # read expected output from memory
        bne     $v1, $s4, exit_fail     # if expected doesn't match actual, jump to fail

scan:
        addi    $s1, $s1, 1             # move input address on byte forward
        lb      $s3, 0($s1)             # load byte
        beq     $s3, $zero, done_scan   # if char null, break loop
        j       scan                    # loop

done_scan:
        addi    $s1, $s1, 1             # move input address on byte past null

        addi    $s2, $s2, 4             # move to next word in output
        sub     $s0, $s0, 1             # decrement num of tests left to run
        bgt     $s0, $zero, run_test    # if more than zero tests to run, jump to run_test

exit_ok:
        la      $a0, okmsg              # put address of okmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        li      $v0, 10                 # 10 is exit with zero status (clean exit)
        syscall

exit_fail:
        la      $a0, failmsg            # put address of failmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        move    $a0, $s1                # print input that failed on
        li      $v0, 4
        syscall

        li      $a0, 1                  # set error code to 1
        li      $v0, 17                 # 17 is exit with error
        syscall

# # Include your implementation here if you wish to run this from the MARS GUI.
# .include "impl.mips"

Tags:

construct:assignment
construct:comment
construct:data
construct:directive
construct:instruction
construct:int
construct:jump
construct:label
construct:laundry
construct:lw
construct:move
construct:number
construct:parameter
construct:register
construct:string
construct:subroutine
construct:syscall
construct:word
paradigm:imperative
paradigm:structured
iHiD commented 1 year ago

Exercise: binary

Code

#
# Test binary_convert with some examples
#
# s0 - num of tests left to run
# s1 - address of input word
# s2 - address of expected output word
# s3 - char byte
# s4 - output word
#
# binary_convert must:
# - be named binary_convert and declared as global
# - read input address of string from a0
# - follow the convention of using the t0-9 registers for temporary storage
# - (if it uses s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning)
# - write integer result to v0

.data

# number of test cases
n: .word 9
# input values (null terminated) & expected output values (word sized ints)
inputs:  .asciiz "0", "1", "10", "11", "100", "1001", "11010", "10001101000", "000011111"
outputs: .word     0,   1,   2,     3,    4,       9,      26,          1128,          31

failmsg: .asciiz "failed for test input: "
okmsg: .asciiz "all tests passed"

.text

main:
        lw      $s0, n
        la      $s1, inputs
        la      $s2, outputs

run_test:
        move    $a0, $s1                # move address of input str to a0
        jal     binary_convert          # call subroutine under test
        move    $v1, $v0                # move return value in v0 to v1 because we need v0 for syscall

        lw      $s4, 0($s2)             # read expected output from memory
        bne     $v1, $s4, exit_fail     # if expected doesn't match actual, jump to fail

.globl binary_convert

binary_convert:
        li      $t0, 1
        move    $v0, $t0

scan:
        addi    $s1, $s1, 1             # move input address on byte forward
        lb      $s3, 0($s1)             # load byte
        beq     $s3, $zero, done_scan   # if char null, break loop
        j       scan                    # loop

done_scan:
        addi    $s1, $s1, 1             # move input address on byte past null

        addi    $s2, $s2, 4             # move to next word in output
        sub     $s0, $s0, 1             # decrement num of tests left to run
        bgt     $s0, $zero, run_test    # if more than zero tests to run, jump to run_test

exit_ok:
        la      $a0, okmsg              # put address of okmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        li      $v0, 10                 # 10 is exit with zero status (clean exit)
        syscall

exit_fail:
        la      $a0, failmsg            # put address of failmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        move    $a0, $s1                # print input that failed on
        li      $v0, 4
        syscall

        li      $a0, 1                  # set error code to 1
        li      $v0, 17                 # 17 is exit with error
        syscall

Tags:

construct:comment
construct:data
construct:directive
construct:globally-visible-label
construct:hexadecimal-number
construct:instruction
construct:integer
construct:label
construct:la
construct:lw
construct:move
construct:number
construct:parameter
construct:register
construct:string
construct:syscall
construct:word
paradigm:imperative
paradigm:structured
iHiD commented 1 year ago

Exercise: binary

Code

#
# Test binary_convert with some examples
#
# s0 - num of tests left to run
# s1 - address of input word
# s2 - address of expected output word
# s3 - char byte
# s4 - output word
#
# binary_convert must:
# - be named binary_convert and declared as global
# - read input address of string from a0
# - follow the convention of using the t0-9 registers for temporary storage
# - (if it uses s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning)
# - write integer result to v0

.data

# number of test cases
n: .word 9
# input values (null terminated) & expected output values (word sized ints)
ins:  .asciiz "0", "1", "10", "11", "100", "1001", "11010", "10001101000", "000011111"
outs: .word     0,   1,   2,     3,    4,       9,      26,          1128,          31

failmsg: .asciiz "failed for test input: "
okmsg: .asciiz "all tests passed"

.text

runner:
        lw      $s0, n
        la      $s1, ins
        la      $s2, outs

run_test:
        move    $a0, $s1                # move address of input str to a0
        jal     binary_convert          # call subroutine under test
        move    $v1, $v0                # move return value in v0 to v1 because we need v0 for syscall

        lw      $s4, 0($s2)             # read expected output from memory
        bne     $v1, $s4, exit_fail     # if expected doesn't match actual, jump to fail

scan:
        addi    $s1, $s1, 1             # move input address on byte forward
        lb      $s3, 0($s1)             # load byte
        beq     $s3, $zero, done_scan   # if char null, break loop
        j       scan                    # loop

done_scan:
        addi    $s1, $s1, 1             # move input address on byte past null

        addi    $s2, $s2, 4             # move to next word in output
        sub     $s0, $s0, 1             # decrement num of tests left to run
        bgt     $s0, $zero, run_test    # if more than zero tests to run, jump to run_test

exit_ok:
        la      $a0, okmsg              # put address of okmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        li      $v0, 10                 # 10 is exit with zero status (clean exit)
        syscall

exit_fail:
        la      $a0, failmsg            # put address of failmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        move    $a0, $s1                # print input that failed on
        li      $v0, 4
        syscall

        li      $a0, 1                  # set error code to 1
        li      $v0, 17                 # 17 is exit with error
        syscall

# IMPLEMENTATION

.globl binary_convert
binary_convert:
    li $t0, 0 # the maximum index
    move $t1, $a0 # copy the address of the argument
    li $t2, 0 # the sum
    index_string:
        lb $t3, 0($t1) # load current char
        beq $t3, $zero, done_index
        # addi $t0, 1 # increment the maximum index
        addi $t1, $t1, 1 # point to the next char
        j index_string
    done_index:
        addi $t1, $t1, -1 # move back from the null char
        li $t4, 1 # 2^n is here
    pr_sum:
        li $t5, 1
        lb $t3, 0($t1) # load current char
        beq $t3, $zero, done_sum
        addi $t3, $t3, -48 # convert char to int
        mul $t5, $t3, $t4 # t5 = 0/1 * 2^n
        add $t2, $t2, $t5
        sll $t4, $t4, 1
        addi $t1, $t1, -1 # traverse back
        j pr_sum
    done_sum:
    move $v0, $t2
    jr $ra

Tags:

No tags generated

iHiD commented 1 year ago

Exercise: octal

Code

#
# Test octal_convert with some examples
#
# s0 - num of tests left to run
# s1 - address of input word
# s2 - address of expected output word
# s3 - char byte
# s4 - output word
#
# octal_convert must:
# - be named octal_convert and declared as global
# - read input address of string from a0
# - follow the convention of using the t0-9 registers for temporary storage
# - (if it uses s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning)
# - write integer result to v0

.data

# number of test cases
n: .word 6
# input values (null terminated) & expected output values (word sized ints)
ins:  .asciiz "1", "10", "17", "130", "2047", "1234567"
outs: .word     1,    8,   15,    88,   1063,    342391

failmsg: .asciiz "failed for test input: "
expectedmsg: .asciiz ". expected "
tobemsg: .asciiz " to be "
okmsg: .asciiz "all tests passed"

.text

runner:
        lw      $s0, n
        la      $s1, ins
        la      $s2, outs

run_test:
        move    $a0, $s1                # move address of input str to a0
        jal     octal_convert           # call subroutine under test
        move    $v1, $v0                # move return value in v0 to v1 because we need v0 for syscall

        lw      $s4, 0($s2)             # read expected output from memory
        bne     $v1, $s4, exit_fail     # if expected doesn't match actual, jump to fail

scan:
        addi    $s1, $s1, 1             # move input address on byte forward
        lb      $s3, 0($s1)             # load byte
        beq     $s3, $zero, done_scan   # if char null, break loop
        j       scan                    # loop

done_scan:
        addi    $s1, $s1, 1             # move input address on byte past null

        addi    $s2, $s2, 4             # move to next word in output
        sub     $s0, $s0, 1             # decrement num of tests left to run
        bgt     $s0, $zero, run_test    # if more than zero tests to run, jump to run_test

exit_ok:
        la      $a0, okmsg              # put address of okmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        li      $v0, 10                 # 10 is exit with zero status (clean exit)
        syscall

exit_fail:
        la      $a0, failmsg            # put address of failmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        move    $a0, $s1                # print input that failed on
        li      $v0, 4
        syscall

        la      $a0, expectedmsg
        li      $v0, 4
        syscall

        move    $a0, $v1                # print actual that failed on
        li      $v0, 1                  # 1 is print integer
        syscall

        la      $a0, tobemsg
        li      $v0, 4
        syscall

        move    $a0, $s4                # print expected value that failed on
        li      $v0, 1                  # 1 is print integer
        syscall

        li      $a0, 1                  # set error code to 1
        li      $v0, 17                 # 17 is exit with error
        syscall

.globl octal_convert
octal_convert:
    li $t0, 0 # the maximum index
    move $t1, $a0 # copy the address of the argument
    li $t2, 0 # the sum
    index_string:
        lb $t3, 0($t1) # load current char
        beq $t3, $zero, done_index
        # addi $t0, 1 # increment the maximum index
        addi $t1, $t1, 1 # point to the next char
        j index_string
    done_index:
        addi $t1, $t1, -1 # move back from the null char
        li $t4, 1 # 8^n is here
    pr_sum:
        li $t5, 1
        lb $t3, 0($t1) # load current char
        beq $t3, $zero, done_sum
        addi $t3, $t3, -48 # convert char to int
        mul $t5, $t3, $t4 # t5 = number * 8^n
        add $t2, $t2, $t5
        sll $t4, $t4, 3
        addi $t1, $t1, -1 # traverse back
        j pr_sum
    done_sum:
    move $v0, $t2
    jr $ra

Tags:

No tags generated

iHiD commented 1 year ago

Exercise: trinary

Code

.text

trinary_convert:

        move    $t0, $a0
        move    $v0, $zero
        li      $t4, 3
        li      $t2, 2

loop:
        lbu     $t1, 0($t0)
        beq     $t1, $zero, done
        subi    $t1, $t1, 0x30
        multu   $v0, $t4
        mflo    $t3
        move    $v0, $t3
        bgt     $t1, $t2, skip
        add     $v0, $v0, $t1
skip:
        addiu   $t0, $t0, 1
        j       loop

done:
        jr      $ra

# vim:syn=asm:et

Tags:

construct:asm
construct:assignment
construct:beq
construct:comment
construct:direct-memory-access
construct:hexadecimal-number
construct:instruction
construct:integer
construct:jump
construct:label
construct:lb
construct:li
construct:loop
construct:move
construct:multu
construct:number
construct:parameter
construct:register
construct:subtraction
construct:tagged-template-string
construct:text
construct:unsigned-number
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:reflective
technique:bit-manipulation
technique:bit-shifting
technique:looping
technique:memory-management
technique:metaprogramming
technique:plain-integer
technique:working-with-bits
iHiD commented 1 year ago

Exercise: hexadecimal

Code

#
# Test hex_convert with some examples
#
# s0 - num of tests left to run
# s1 - address of input word
# s2 - address of expected output word
# s3 - char byte
# s4 - output word
#
# hex_convert must:
# - be named hex_convert and declared as global
# - read input address of string from a0
# - follow the convention of using the t0-9 registers for temporary storage
# - (if it uses s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning)
# - write integer result to v0

.data

# number of test cases
n: .word 9
# input values (null terminated) & expected output values (word sized ints)
ins:  .asciiz "1", "C", "10", "af", "100", "19ACE", "000000", "ffff00", "00fff0"
outs: .word     1,  12,   16,  175,   256,  105166,        0, 16776960,    65520

failmsg: .asciiz "failed for test input: "
expectedmsg: .asciiz ". expected "
tobemsg: .asciiz " to be "
okmsg: .asciiz "all tests passed"

.text

runner:
        lw      $s0, n
        la      $s1, ins
        la      $s2, outs

run_test:
        move    $a0, $s1                # move address of input str to a0
        jal     hex_convert             # call subroutine under test
        move    $v1, $v0                # move return value in v0 to v1 because we need v0 for syscall

        lw      $s4, 0($s2)             # read expected output from memory
        bne     $v1, $s4, exit_fail     # if expected doesn't match actual, jump to fail

scan:
        addi    $s1, $s1, 1             # move input address on byte forward
        lb      $s3, 0($s1)             # load byte
        beq     $s3, $zero, done_scan   # if char null, break loop
        j       scan                    # loop

done_scan:
        addi    $s1, $s1, 1             # move input address on byte past null

        addi    $s2, $s2, 4             # move to next word in output
        sub     $s0, $s0, 1             # decrement num of tests left to run
        bgt     $s0, $zero, run_test    # if more than zero tests to run, jump to run_test

exit_ok:
        la      $a0, okmsg              # put address of okmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        li      $v0, 10                 # 10 is exit with zero status (clean exit)
        syscall

exit_fail:
        la      $a0, failmsg            # put address of failmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        move    $a0, $s1                # print input that failed on
        li      $v0, 4
        syscall

        la      $a0, expectedmsg
        li      $v0, 4
        syscall

        move    $a0, $v1                # print actual that failed on
        li      $v0, 1                  # 1 is print integer
        syscall

        la      $a0, tobemsg
        li      $v0, 4
        syscall

        move    $a0, $s4                # print expected value that failed on
        li      $v0, 1                  # 1 is print integer
        syscall

        li      $a0, 1                  # set error code to 1
        li      $v0, 17                 # 17 is exit with error
        syscall

.globl hex_convert
hex_convert:
    li $t0, 0 # the maximum index
    move $t1, $a0 # copy the address of the argument
    li $t2, 0 # the sum
    index_string:
        lb $t3, 0($t1) # load current char
        beq $t3, $zero, done_index
        # addi $t0, 1 # increment the maximum index
        addi $t1, $t1, 1 # point to the next char
        j index_string
    done_index:
        addi $t1, $t1, -1 # move back from the null char
        li $t4, 1 # 16^n is here
    pr_sum:
        li $t5, 1
        lb $t3, 0($t1) # load current char
        beq $t3, $zero, done_sum
        bge $t3, 57, letter
        addi $t3, $t3, -48 # convert char to int
        j letter_end
        letter:
        addi $t3, $t3, -55 # convert letters to 10-15
        letter_end:
        mul $t5, $t3, $t4 # t5 = (0-F) * 16^n
        add $t2, $t2, $t5
        sll $t4, $t4, 4
        addi $t1, $t1, -1 # traverse back
        j pr_sum
    done_sum:
    move $v0, $t2
    jr $ra

Tags:

No tags generated

iHiD commented 1 year ago

Exercise: hexadecimal

Code

.text

hex_convert:

        move    $t0, $a0
        move    $v0, $zero
        li      $t5, 10
        li      $t6, 0xDF
        li      $t7, 5

loop:
        lbu     $t1, 0($t0)
        beq     $t1, $zero, done
        move    $t2, $t1
        subi    $t1, $t1, 0x30
        blt     $t1, $t5, convert
        and     $t1, $t2, $t6
        subi    $t1, $t1, 0x41
        bgt     $t1, $t7, skip
        add     $t1, $t1, $t5

convert:

        sll     $v0, $v0, 4
        add     $v0, $v0, $t1

skip:
        addiu   $t0, $t0, 1
        j       loop

done:
        jr      $ra

# vim:syn=asm:et

Tags:

construct:asm
construct:and
construct:assignment
construct:beq
construct:comment
construct:direct-memory-access
construct:hexadecimal-number
construct:instruction
construct:integer
construct:jump
construct:label
construct:li
construct:loop
construct:move
construct:number
construct:parameter
construct:register
construct:shift-left
construct:subtraction
construct:tagged-template-string
construct:word
paradigm:imperative
paradigm:reflective
technique:bit-manipulation
technique:bit-shifting
technique:looping
iHiD commented 1 year ago

Exercise: hexadecimal

Code

hex_convert:
    move    $t1,$zero
    move    $v0,$zero

sum:                
    add     $t2,$a0,$t1     #add index to address
    lb      $t2,0($t2)      #t2 = character 
    beq     $t2,$zero,done
    sll     $v0,$v0,4

    addi    $t3,$zero,65
    slt     $t3,$t2,$t3
    bne     $t3,$zero,num

    addi    $t3,$zero,97
    slt     $t3,$t2,$t3
    bne     $t3,$zero,lowercase
    j       uppercase

num:                        #t2 - 48
    addi    $t2,$t2,-48
    add     $v0,$t2,$v0
    addi    $t1,$t1,1       #increment index
    j       sum

lowercase:                  #t2 - 55
    addi    $t2,$t2,-55
    add     $v0,$t2,$v0
    addi    $t1,$t1,1       #increment index
    j       sum

uppercase:                  #t2 - 87
    addi    $t2,$t2,-87
    add     $v0,$t2,$v0
    addi    $t1,$t1,1       #increment index
    j       sum

done:
    jr      $ra

Tags:

construct:add
construct:addi
construct:assignment
construct:beq
construct:bne
construct:comment
construct:function
construct:hexadecimal-number
construct:instruction
construct:int
construct:jump
construct:label
construct:lb
construct:move
construct:number
construct:parameter
construct:return
construct:shift-left
construct:slt
construct:tag
construct:unconditional-jump
construct:variable
construct:visibility
paradigm:imperative
paradigm:procedural
technique:bit-manipulation
technique:bit-shifting
technique:branching
technique:logical-operators
iHiD commented 1 year ago

Exercise: leap

Code

#
# Test is_leap_year with some examples
#
# s0 - num of tests left to run
# s1 - address of input word
# s2 - address of expected output word
# s3 - input word
# s4 - output word
#
# is_leap_year must:
# - be named is_leap_year and declared as global
# - read input integer from a0
# - follow the convention of using the t0-9 registers for temporary storage
# - (if it wants to use s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning)
# - write boolean result to v0

.data

n: .word 7                      # number of test cases
ins:  .word 1996, 1997, 1998, 1900, 1800, 2400, 2000  # input years
outs: .word    1,    0,    0,    0,    0,    1,    1  # expected result

failmsg: .asciiz "failed for test input: "
okmsg: .asciiz "all tests passed"

.text

runner:
        lw      $s0, n
        la      $s1, ins
        la      $s2, outs

run_test:
        lw      $s3, 0($s1)             # read input from memory
        move    $a0, $s3                # move it to a0
        jal     is_leap_year            # call subroutine under test
        move    $v1, $v0                # move return value in v0 to v1 because we need v0 for syscall

        lw      $s4, 0($s2)             # read expected output from memory
        bne     $v1, $s4, exit_fail     # if expected doesn't match actual, jump to fail

        addi    $s1, $s1, 4             # move to next word in input
        addi    $s2, $s2, 4             # move to next word in output
        sub     $s0, $s0, 1             # decrement num of tests left to run
        bgt     $s0, $zero, run_test    # if more than zero tests to run, jump to run_test

exit_ok:
        la      $a0, okmsg              # put address of okmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        li      $v0, 10                 # 10 is exit with zero status (clean exit)
        syscall

exit_fail:
        la      $a0, failmsg            # put address of failmsg into a0
        li      $v0, 4                  # 4 is print string
        syscall

        move    $a0, $s3                # set arg of syscall to input that failed the test
        li      $v0, 1                  # 1 is print int
        syscall

        li      $a0, 1                  # set exit code to 1
        li      $v0, 17                 # terminate with the exit code in $a0
        syscall

.globl is_leap_year
is_leap_year:
    li $t0, 4
    div $a0, $t0
    mfhi $t1
    beq $t1, 0, leap
    li $v0, 0
    jr $ra
    leap:
    li $v0, 1
    jr $ra

Tags:

construct:asciiz
construct:add
construct:addi
construct:address
construct:assignment
construct:branch
construct:comment
construct:data-definition
construct:directive
construct:div
construct:divide
construct:global-label
construct:goto
construct:immediate
construct:instruction
construct:int
construct:integral-number
construct:jump
construct:label
construct:la
construct:lw
construct:macro
construct:memory-access
construct:move
construct:number
construct:parameter
construct:pseudo-instruction
construct:readme
construct:register
construct:return
construct:string
construct:sub
construct:subroutine
construct:syscall
construct:tagged-union
construct:text
construct:variable
construct:word
paradigm:imperative
paradigm:structured
iHiD commented 1 year ago

Exercise: difference-of-squares

Code

.globl difference_of_squares

# a0: N
# t0: i
# t1: i squared
# t2: square_of_sums
# t3: sum_of_squares
# t4: loop condition check
# v0: result
difference_of_squares:
        li      $t0, 1                  # initiialize i to 1
        li      $t2, 0                  # initialize square_of_sums to 0
        li      $t3, 0                  # initialize sum_of_squares to 0
        addi    $a0, $a0, 1             # add 1 to N for loop condition

loop:
        sltu    $t4, $t0, $a0           # is i < N + 1?
        beq     $t4, $zero, exit_loop   # if i >= N + 1 exit the loop

        add     $t2, $t2, $t0           # add i to square_of_sums
        mul     $t1, $t0, $t0           # square i
        add     $t3, $t3, $t1           # add squared i to sum of squares

        addi    $t0, $t0, 1             # increment i by 1
        j       loop
exit_loop:
        mul     $t2, $t2, $t2           # square the sum of i to get square of sums
        sub     $v0, $t2, $t3           # result = square_of_sums - sum_of_squares
        jr      $ra

Tags:

construct:add
construct:addi
construct:assignment
construct:beq
construct:comment
construct:directed-jump
construct:instruction
construct:int
construct:label
construct:li
construct:loop
construct:mul
construct:multiply
construct:named-operand
construct:number
construct:parameter
construct:return
construct:subtract
construct:unsigned-int
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:looping
paradigm:multiparadigm
paradigm:procedural
technique:bit-manipulation
technique:bit-shifting
technique:bitwise-operations
technique:looping
iHiD commented 1 year ago

Exercise: hamming

Code

# Calculate the hamming distance of two strings

# $a0 - pointer to string 1
# $a1 - pointer to string 2
# $v0 - output, integer form of binary string
# $t0 - character of string 1
# $t1 - character of string 2
# $t2 - are the characters different?

.globl hamming_distance

hamming_distance:
        li      $v0, 0                  # Reset accumulator to 0.

loop:
        lb      $t0, 0($a0)             # Load a character of string 1,
        beq     $t0, $zero, end         # if it is null then return.
        lb      $t1, 0($a1)             # Otherwise also load a character of string 2.

        sne     $t2, $t0, $t1           # Determine if characters are different
        addu    $v0, $v0, $t2           # and add the difference to accumulator.

        addi    $a0, $a0, 1             # Finally, increment the pointer for string 1
        addi    $a1, $a1, 1             # and for string 2
        j       loop                    # and loop.

end:
        jr $ra

Tags:

construct:addu
construct:assignment
construct:beq
construct:comment
construct:directed-jump
construct:instruction
construct:integer
construct:jump
construct:label
construct:load
construct:parameter
construct:register
construct:return
construct:string
construct:unsigned
construct:word
iHiD commented 1 year ago

Exercise: rna-transcription

Code

.globl transcribe_rna

.text

transcribe_rna:
    move $t1, $a0    # input address
    move $t0, $a1    # output address

loop:
    lb $t2, 0($t1)
    beqz $t2, return
    beq $t2, 65, trans_a
    beq $t2, 67, trans_c
    beq $t2, 71, trans_g
    beq $t2, 84, trans_t

trans_a:
    li $t2, 85       # A:65 => U:85
    j next_grand

trans_c:             # C:67 => G:71
    li $t2, 71
    j next_grand

trans_g:
    li $t2, 67       # G:71 => C:67
    j next_grand

trans_t:
    li $t2, 65       # T:84 => A:65

next_grand:
    sb $t2, 0($t0)
    addi $t0, $t0, 1
    addi $t1, $t1, 1
    j loop

return:
    move $v0, $a1
    jr $ra

Tags:

construct:add
construct:assignment
construct:beq
construct:beqz
construct:comment
construct:function
construct:instruction
construct:integer
construct:jump
construct:label
construct:li
construct:move
construct:number
construct:parameter
construct:register
construct:tagged-argument
construct:tagged-union
construct:text
construct:unconditional-jump
construct:variable
construct:visibility
paradigm:imperative
paradigm:structured
iHiD commented 1 year ago

Exercise: isogram

Code

# Determine if the given string is an isogram, meaning that the same character
# does not appear more than once.
#
# Strategy: use the bits of a single word to represent set of encountered letters
#
# $a0 - input, pointer to null-terminated string of chars 0-7
# $v0 - output, boolean representing is or is not isogram
# $t0 - set of bits
# $t1 - an encountered character

.globl is_isogram

is_isogram:
        li      $t0, 0                  # Reset set to 0.

loop:
        lb      $t1, 0($a0)             # Load a character,
        beq     $t1, $zero, true        # if end of string, return true.

        addi    $t2, $t1, -65           # If less than 'A'...
        blt     $t2, $zero, increment   # continue to next letter.

        addi    $t1, $t1, -97           # Find offset from 'a'.
        blt     $t1, $zero, downcase    # If negative, presume upper case, so downcase

consider_seen:
        li      $t3, 1
        sllv    $t3, $t3, $t1           # Create bit mask
        and     $t4, $t0, $t3           # Apply to set.
        bgt     $t4, $zero, false       # If char has been seen, return false.

        or      $t0, $t0, $t3           # Otherwise flip bit for char

increment:
        addi    $a0, $a0, 1             # Finally, increment the pointer
        j       loop                    # and loop.

downcase:
        addi    $t1, $t1, 32            # Upper -> lower ascii value
        j       consider_seen

false:
        li      $v0, 0
        jr      $ra

true:
        li      $v0, 1
        jr      $ra

Tags:

construct:add
construct:addi
construct:and
construct:assignment
construct:beq
construct:bitwise-and
construct:bitwise-or
construct:comment
construct:constant
construct:direct-memory-access
construct:instruction
construct:int
construct:jump
construct:label
construct:left-shift
construct:load
construct:logical-and
construct:or
construct:parameter
construct:register
construct:return
construct:right-shift
construct:set-bit
construct:string
construct:subtract
construct:unsigned-number
construct:word
paradigm:imperative
paradigm:low-level
technique:bit-manipulation
technique:bit-shifting
technique:boolean-logic
technique:looping
iHiD commented 1 year ago

Exercise: isogram

Code

.globl is_isogram

.text

is_isogram:
    move $t0, $a0
    li $t1, 0

loop:
    lbu $t2, 0($t0)
    beqz $t2, set_true
    blt $t2, 65, next
    bgt $t2, 90, check_letter
    add $t2, $t2, 32

check_letter:
    bgt $t2, 122, next
    sub $t2, $t2, 97
    li $t3, 1
    sllv $t3, $t3, $t2
    and $t4, $t3, $t1
    bgtz $t4, set_false
    or $t1, $t1, $t3

next:
    add $t0, $t0, 1
    j loop

set_true:
    li $t5, 1
    j return

set_false:
    li $t5, 0

return:
    move $v0, $t5
    jr $ra

Tags:

construct:add
construct:and
construct:assignment
construct:beq
construct:beqz
construct:branch
construct:compare
construct:direct-memory-access
construct:instruction
construct:int
construct:integral-number
construct:invocation
construct:jump
construct:label
construct:li
construct:load
construct:logical-and
construct:logical-or
construct:loop
construct:move
construct:number
construct:or
construct:parameter
construct:register
construct:shift-left
construct:sub
construct:tagged-union
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:logical
paradigm:procedural
technique:boolean-logic
technique:looping
iHiD commented 1 year ago

Exercise: triangle

Code

triangle:
    add     $t0,$a0,$a1
    slt     $t0,$t0,$a2
    bne     $t0,$zero,invalid

    add     $t0,$a1,$a2
    slt     $t0,$t0,$a0
    bne     $t0,$zero,invalid

    add     $t0,$a0,$a2
    slt     $t0,$t0,$a1
    bne     $t0,$zero,invalid

    beq     $a0,$a1,check_equilateral
    beq     $a0,$a2,isoceles
    beq     $a1,$a2,isoceles

    j       scalene

check_equilateral:
    bne     $a0,$a2,isoceles
    beq     $a0,$zero,invalid
    j       equilateral

scalene:
    move    $v0,$zero
    jr      $ra

isoceles:
    addi    $v0,$zero,1
    jr      $ra

equilateral:
    addi    $v0,$zero,2
    jr      $ra

invalid:
    addi    $v0,$zero,3
    jr      $ra

Tags:

construct:add
construct:addi
construct:assembly
construct:beq
construct:bne
construct:branch
construct:goto
construct:instruction
construct:integer
construct:jump
construct:label
construct:move
construct:parameter
construct:register
construct:slt
construct:tagged
construct:technique
construct:triangle
iHiD commented 1 year ago

Exercise: triangle

Code

.globl  triangle

# a0: a
# a1: b
# a2: c
triangle:
        add     $t0, $a0, $a1                   # t0 = a + b
        ble     $t0, $a2, invalid               # a + b <= c?
        add     $t0, $a0, $a2                   # t0 = a + c
        ble     $t0, $a1, invalid               # a + c <= b
        add     $t0, $a1, $a2                   # t0 = b + c
        ble     $t0, $a0, invalid               # b + c <= a

        beq     $a0, $a1, equilat_test          # a == b?
        beq     $a1, $a2, isoceles              # b == c?
        beq     $a0, $a2, isoceles              # a == c?
        j       scalene
equilat_test:
        beq     $a1, $a2, equilateral           # b == c?
        j       isoceles
scalene:
        li      $v0, 0
        j       exit
isoceles:
        li      $v0, 1
        j       exit
equilateral:
        li      $v0, 2
        j       exit
invalid:
        li      $v0, 3
exit:
        jr      $ra

Tags:

construct:add
construct:assignment
construct:beq
construct:comment
construct:direct_jump
construct:goto
construct:instruction
construct:int
construct:integral_number
construct:label
construct:less-than
construct:li
construct:number
construct:parameter
construct:register
construct:return
construct:tag
construct:variable
construct:visibility
paradigm:imperative
paradigm:structured
technique:jumping
iHiD commented 1 year ago

Exercise: atbash-cipher

Code

.globl  atbash_cipher

# a0 - input string, for callee
# a1 - pointer to output string, for callee

# t0 - copy of output string
# t1 - current input char
# t2 - char counter, when reaches 5 insert space
# t3 - current output character
# t4 - cipher lookup base address
# t5 - char offset
# t6 - copy of input string
atbash_cipher:
        move    $t0, $a1                        # save copy of output string
        move    $t6, $a0                        # save copy of input string
        li      $t2, 0                          # initialize char counter
        la      $t4, cipher_lookup              # load cipher base address
loop:
        lb      $t1, 0($t6)                     # read input char
        beq     $t1, $zero, exit                # if char is NULL finish
        blt     $t1, 65, increment_input        # skip whitespace
        bgt     $t1, 96, is_lower_case          # check if already lowercase
        addi    $t1, $t1, 32                    # convert char to lowercase
is_lower_case:
        blt     $t2, 5, write_char              # if space counter is 5 add whitespace to output
        li      $t3, 32                         # 32 = SPACE
        sb      $t3, 0($t0)                     # write space in output string 
        addi    $t0, $t0, 1                     # increment output index
        li      $t2, 0                          # reset char counter
write_char:
        addi    $t5, $t1, -97                   # get char offset in alphabet
        sll     $t5, $t5, 2                     # convert offset into bytes
        add     $t5, $t5, $t4                   # add cipher base offset to char offset
        lb      $t3, 0($t5)                     # load output char from lookup
        sb      $t3, 0($t0)
        addi    $t2, $t2, 1                     # increment char counter

        addi    $t0, $t0, 1                     # increment output index
increment_input:
        addi    $t6, $t6, 1                     # increment input index
        j       loop
exit:
        sb      $zero, 0($t0)
        jr      $ra

.data
cipher_lookup: .word 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97

Tags:

construct:add
construct:addi
construct:assignment
construct:beq
construct:comment
construct:data
construct:direct-memory-access
construct:globally-unique-id
construct:instruction
construct:integer
construct:jump
construct:label
construct:la
construct:lb
construct:li
construct:move
construct:number
construct:parameter
construct:register
construct:shift-left
construct:store
construct:string
construct:tag
construct:word
paradigm:imperative
paradigm:structured
technique:bit-manipulation
technique:bit-shifting
technique:looping
iHiD commented 1 year ago

Exercise: scrabble-score

Code

# SCORES: 
# A, E, I, O, U, L, N, R, S, T       1
# D, G                               2
# B, C, M, P                         3
# F, H, V, W, Y                      4
# K                                  5
# J, X                               8
# Q, Z                               10

.data 
    input: .asciiz "ab"
            # a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p,  q, r, s, t, u, v, w, x, y, z
    scores: .word 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 

.text
# la    $a0, input      # load input into a0 for test
scrabble_score:
    move    $t9, $ra    # save test address
    move    $a3, $a0    # save original input address from test 
    jal buildScoreCard  # returns to t0 the address of list of scores by index 
    addi    $t3, $zero, 0   # set total score to zero 
    move    $t0, $v0    # reset t0 to heap address 
    move    $a0, $a3    # reset a0 to be a3 to get test input
    jal     scoreWord   # returns score in $t3 
    j   returnToTest
#   j   exit        # for local tests

# $t0 = heap address
# a0 = start of input word
# $t3 = final score of word 
scoreWord:
    lb  $t2, ($a0)  # load first byte into t2
    beqz    $t2, jumpToRa   # if byte is null char jump back to parent function
    addi    $t4, $zero, 90  #
    bgt     $t2, $t4, subtract97 # lowercase letter scenerio
    #fall through for uppercase letters
    subi    $t2, $t2, 65    # subtract 97 to get a value 0 - 26
    # end fall through 
    loop:
    mul     $t2, $t2, 4     # get word value * 4 to figure out how many bytes into heap to jump
    add $t2, $t0, $t2   # heap start + number of bytes to skip
    lw  $t2, ($t2)  # load word value at that address to t2
    add $t3, $t3, $t2,  # add the score value to total
    addi    $a0, $a0, 1 # increament word address by 1 bytes 
    j   scoreWord   # recurse to score next byte

subtract97: 
    subi    $t2, $t2, 97
    j loop          # jump back to scoreWord loop   

buildScoreCard: 
    # get heap allocation 4 * 26 (4 bytes per int) 
    addi    $a0, $zero, 26  # number of available letters a0 
    mul     $a0, $a0, 4     # multiply by 4 to get total number of needs bytes from heap 
    addi    $v0, $zero, 9   # syscall for heap allocation, returns into v0
    syscall
    move    $t0, $v0    # copy heap address into t0
    la  $a0, scores # load scores address into a0
                # fall through continue to loadScoreCard    
                # t0 = heap address (also saved in v0)
                # a0 = scores address 
loadScoreCard:
    lw  $t1, ($a0)  # load word (score) into t1
    beqz    $t1, jumpToRa   # exit loop if no more values
    sw  $t1, ($t0)  # store the int at t0 address of heap 
    addi    $t0, $t0, 4     # increament t0 heap by 4 bytes 
    addi    $a0, $a0, 4 # increament store address 
    j loadScoreCard     # recurse until loaded

jumpToRa: 
    jr  $ra

returnToTest: 
    move    $v0, $t3    # 
    jr  $t9         # jump back to test caller  

exit:
    addi    $v0, $zero, 10  # exit call
    syscall

Tags:

No tags generated

iHiD commented 1 year ago

Exercise: scrabble-score

Code

.data
    .align 2

values: .word 1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,1,1,1,1,4,4,8,4,10

.text 

scrabble_score:
    move    $t0,$a0
    move    $v0,$zero
    la      $t7,values
    j       loop

loop: 
    lb      $t1,0($t0)
    beq     $t1,$zero,done

    addi    $t2,$zero,97
    slt     $t2,$t1,$t2
    bne     $t2,$zero,offset

    addi    $t1,$t1,-32

    j       offset

offset:
    addi    $t6,$zero,65
    sub     $t6,$t1,$t6

    addi    $t2,$zero,4
    mult    $t2,$t6
    mflo    $t6

    add     $t2,$t6,$t7
    lw      $t2,0($t2)
    add     $v0,$v0,$t2

    addi    $t0,$t0,1
    j       loop

done:
    jr      $ra

Tags:

construct:assembly
construct:beq
construct:bne
construct:data
construct:directive
construct:goto
construct:instruction
construct:int
construct:label
construct:la
construct:lb
construct:load
construct:method
construct:mult
construct:number
construct:parameter
construct:register
construct:sub
construct:text
construct:variable
construct:word
paradigm:imperative
paradigm:structured
technique:bit-manipulation
technique:bit-shifting
technique:looping
technique:math:bitwise-operations
technique:math:multiplication
uses:Scrabbles
iHiD commented 1 year ago

Exercise: scrabble-score

Code

.globl scrabble_score

.data

#            A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q   R  S  T  U  V  W  X  Y Z
score: .word 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4 10

.text

scrabble_score:
    li $t0, 0               # init result
    la $t1, score           # load score array address
    move $t2, $a0           # get input string address

loop:
    lb $t3, 0($t2)          # load byte
    beqz $t3, return        # return if end of input
    bge $t3, 97, cal_score  # lowercase
    add $t3, $t3, 32        # uppercase to lowercase

cal_score:
    sub $t3, $t3, 97        # to array index
    add $t3, $t3, $t3       # calculate array address offset
    add $t3, $t3, $t3       #
    add $t3, $t3, $t1       # get score address
    lw $t4, 0($t3)          # load score
    add $t0, $t0, $t4       # add to result
    addi $t2, $t2, 1        # next character
    j loop

return:
    move $v0, $t0
    jr $ra

Tags:

construct:add
construct:addi
construct:address
construct:assignment
construct:beq
construct:comment
construct:data-definition
construct:direct-memory-access
construct:globally-visible-routine
construct:instruction
construct:jump
construct:label
construct:la
construct:load
construct:lw
construct:move
construct:multiply
construct:named-operands
construct:number
construct:parameter
construct:register
construct:return
construct:string
construct:sub
construct:tagged-union
construct:text
construct:word
paradigm:imperative
paradigm:reflective
technique:bit-manipulation
technique:bit-shifting
technique:looping
ErikSchierboom commented 1 year ago

This is an automated comment

Hello :wave: Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!