Question
The parts that need to be changed in main are between the comment lines Your part starts here and Your part ends here. You should
The parts that need to be changed in main are between the comment lines Your part starts here and Your part ends here. You should also add more lines to the register assignment table, to describe what you did. Additional comments will probably be helpful. There are also two character strings that need to be changed, to put your names in the output.
Here are the Mars Messages and Run I/O panels, after assembling and running the starter program.
Assemble: assembling /.../lab2.asm Assemble: operation completed successfully. Go: running lab2.asm Go: execution completed successfully.
CMPEN 331 Lab 2 Student's name 0 0x00000000 0x00000003 00000000000000000000000000000000 00000000000000000000000000000011 1 0x00000024 0x00000003 00000000000000000000000000100100 00000000000000000000000000000011 2 0x0000007e 0x00000003 00000000000000000000000001111110 00000000000000000000000000000011 3 0x0000007f 0x00000003 00000000000000000000000001111111 00000000000000000000000000000011 4 0x00000080 0x00000003 00000000000000000000000010000000 00000000000000000000000000000011 5 0x000000a2 0x00000003 00000000000000000000000010100010 00000000000000000000000000000011 6 0x00000627 0x00000003 00000000000000000000011000100111 00000000000000000000000000000011 7 0x000007ff 0x00000003 00000000000000000000011111111111 00000000000000000000000000000011 8 0x00000800 0x00000003 00000000000000000000100000000000 00000000000000000000000000000011 9 0x000020ac 0x00000003 00000000000000000010000010101100 00000000000000000000000000000011 10 0x00002233 0x00000003 00000000000000000010001000110011 00000000000000000000000000000011 11 0x0000ffff 0x00000003 00000000000000001111111111111111 00000000000000000000000000000011 12 0x00010000 0x00000003 00000000000000010000000000000000 00000000000000000000000000000011 13 0x00010348 0x00000003 00000000000000010000001101001000 00000000000000000000000000000011 14 0x00022e13 0x00000003 00000000000000100010111000010011 00000000000000000000000000000011 15 0x0010ffff 0x00000003 00000000000100001111111111111111 00000000000000000000000000000011 16 0x89abcdef 0x00000003 10001001101010111100110111101111 00000000000000000000000000000011
All done!
-- program is finished running
Your output should be the same, except for the name, and the value of n that is printed (it's a constant 3 in the starter version). The assignment is based on a short function used in the implementation of the UTF-8 data format. Here are some descriptions of UTF-8:
The idea behind UTF-8 is to augment a character code with some additional bits to protect against certain kinds of communication failures. Here is the standard diagram:
Char. number range | UTF-8 octet sequence (hexadecimal) | (binary)
----------------------+------------------------------------- 0000 0000 - 0000 007F | 0xxxxxxx 0000 0080 - 0000 07FF | 110xxxxx 10xxxxxx 0000 0800 - 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000 - 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
The term "octet" means "8 bits", which everyone now thinks of as one byte. There were once computers whose byte size was not 8 bits, but they are all gone now.
The basic if-then-else structure, from write_utf8(), is
if (code_point < 0x80) { ... case 1
} else if (code_point <= 0x7FF) { ... case 2
} else if (code_point <= 0xFFFF) { ... case 3
} else if (code_point <= 0x10FFFF) { ... case 4
} else { ... case 5
}
In the starter version provided, we used the variable j instead of code_point. Each case should compute n from j.
It's going to be a lot easier if you sketch the solution in C, and then rewrite it into MIPS assembler, inserting the C version as a comment. Start with the if-then-else structure, and test that with some bogus values for n. Then, write each of the five cases separately; two of these are trivial, and the other three have a lot of features in common.
The MIPS assembly code is slightly easier to write if all the tests are < instead of a mixture of < and <= . Also, treat the registers as if they contain unsigned integers (when using a numeric instruction) or simple bit strings (when using logical and shift instructions).
In case 1, j fits in 7 bits, and it is expanded to 8 bits with a leading 0 bit, which yields the same value. In case 5, it's an error, so n is -1 or 0xFFFFFFFF; that's not the proper treatment of errors according to UTF-8, but it's certainly easier.
The following comments describe how the bits of j are to be rearranged to form the bits of n.
if (j < 0x80) {
// j fits in 7 bits, expand to 8 bits // n = j
} else if (j <= 0x7FF) { // j fits in 11 bits, expand to 16 bits // b = low 6 bits of j // a = next 5 bits of j // n = 110 a 10 b //
// j= //
// n=
aaaaa 352 110 aaaaa 10 } else if (j <= 0xFFFF) {
bbbbbb 6 bits out
// j fits in 16 bits, expand to 24 bits // c = low 6 bits of j // b = next 6 bits of j // a = next 4 bits of j
// n = 1110 a 10 b 10 c
4
6 bits out
46 aaaa bbbbbb 42 62
// // j= // // n = 1110 aaaa 10 bbbbbb 10 cccccc
} else if (j <= 0x10FFFF) { // j fits in 21 bits, expand to 32 bits // d = low 6 bits of j // c = next 6 bits of j // b = next 6 bits of j // a = next 3 bits of j // n = 11110 a 10 b 10 c 10 d
5 6 bits in
bbbbbb
366 aaa bbbbbb cccccc 532 62 62
// // // // n = 11110 aaa 10 bbbbbb 10 cccccc 10 dddddd
j=
6 bits in dddddd
} else { // j is outside the UTF-8 range of character codes // n = 0xFFFFFFFF
}
6 bits in cccccc
Here is the output from a correct solution, using MARS. The name strings have not been changed - be sure you do that.
6 bits out
CMPEN 331 Lab 2 Student's name 0 0x00000000 0x00000000 00000000000000000000000000000000 00000000000000000000000000000000 1 0x00000024 0x00000024 00000000000000000000000000100100 00000000000000000000000000100100 2 0x0000007e 0x0000007e 00000000000000000000000001111110 00000000000000000000000001111110 3 0x0000007f 0x0000007f 00000000000000000000000001111111 00000000000000000000000001111111 4 0x00000080 0x0000c280 00000000000000000000000010000000 00000000000000001100001010000000 5 0x000000a2 0x0000c2a2 00000000000000000000000010100010 00000000000000001100001010100010 6 0x00000627 0x0000d8a7 00000000000000000000011000100111 00000000000000001101100010100111 7 0x000007ff 0x0000dfbf 00000000000000000000011111111111 00000000000000001101111110111111 8 0x00000800 0x00e0a080 00000000000000000000100000000000 00000000111000001010000010000000 9 0x000020ac 0x00e282ac 00000000000000000010000010101100 00000000111000101000001010101100 10 0x00002233 0x00e288b3 00000000000000000010001000110011 00000000111000101000100010110011 11 0x0000ffff 0x00efbfbf 00000000000000001111111111111111 00000000111011111011111110111111 12 0x00010000 0xf0908080 00000000000000010000000000000000 11110000100100001000000010000000 13 0x00010348 0xf0908d88 00000000000000010000001101001000 11110000100100001000110110001000 14 0x00022e13 0xf0a2b893 00000000000000100010111000010011 11110000101000101011100010010011 15 0x0010ffff 0xf48fbfbf 00000000000100001111111111111111 11110100100011111011111110111111 16 0x89abcdef 0xffffffff 10001001101010111100110111101111 11111111111111111111111111111111 All done!
-- program is finished running
HERE IS THE CODE FOR EDITING
# CMPEN 331, Lab 2
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# switch to the Data segment .data # global data is defined here
# Don't forget the backslash-n (newline character) Homework: .asciiz "CMPEN 331 Homework 2 " Name_1: .asciiz "First Person's name " Name_2: .asciiz "Second Person's name "
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - I # switch to the Text segment .text # the program is defined here
.globl main main: # Whose program is this? la $a0, Homework jal Print_string la $a0, Name_1 jal Print_string la $a0, Name_2 jal Print_string # int i, j = 2, n = 3; # for (i = 0; i <= 16; i++) # { # ... j = testcase[i] # ... calculate n from j # ... print i, j and n # } # register assignments # $s0 i # $s1 j = testcase[i] # $s2 n # $t0 address of testcase[i] # $a0 argument to Print_integer, Print_string, etc. # add to this list if you use any other registers
# initialization li $s1, 2 # j = 2 li $s2, 3 # n = 3 # for (i = 0; i <= 16; i++) li $s0, 0 # i = 0 la $t0, testcase # address of testcase[i] bgt $s0, 16, bottom top: lw $s1, 0($t0) # j = testcase[i] # calculate n from j # Your part starts here # Your part ends here # print i, j and n move $a0, $s0 # i jal Print_integer la $a0, sp # space jal Print_string move $a0, $s1 # j jal Print_hex la $a0, sp # space jal Print_string move $a0, $s2 # n jal Print_hex la $a0, sp # space jal Print_string move $a0, $s1 # j jal Print_bin la $a0, sp # space jal Print_string move $a0, $s2 # n jal Print_bin la $a0, nl # newline jal Print_string # for (i = 0; i <= 16; i++) addi $s0, $s0, 1 # i++ addi $t0, $t0, 4 # address of testcase[i] ble $s0, 16, top # i <= 16 bottom: la $a0, done # mark the end of the program jal Print_string jal Exit0 # end the program, default return status
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.data # global data is defined here sp: .asciiz " " # space nl: .asciiz " " # newline done: .asciiz "All done! "
testcase: # UTF-8 representation is one byte .word 0x0000 # nul # Basic Latin, 0000 - 007F .word 0x0024 # $ (dollar sign) .word 0x007E # ~ (tilde) .word 0x007F # del
# UTF-8 representation is two bytes .word 0x0080 # pad # Latin-1 Supplement, 0080 - 00FF .word 0x00A2 # cent sign .word 0x0627 # Arabic letter alef .word 0x07FF # unassigned
# UTF-8 representation is three bytes .word 0x0800 .word 0x20AC # Euro sign .word 0x2233 # anticlockwise contour integral sign .word 0xFFFF
# UTF-8 representation is four bytes .word 0x10000 .word 0x10348 # Hwair, see http://en.wikipedia.org/wiki/Hwair .word 0x22E13 # randomly-chosen character .word 0x10FFFF
.word 0x89ABCDEF # randomly chosen bogus value
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Wrapper functions around some of the system calls # See P&H COD, Fig. A.9.1, for the complete list.
.text
.globl Print_integer Print_integer: # print the integer in register $a0 (decimal) li $v0, 1 syscall jr $ra
.globl Print_string Print_string: # print the string whose starting address is in register $a0 li $v0, 4 syscall jr $ra
.globl Exit Exit: # end the program, no explicit return status li $v0, 10 syscall jr $ra # this instruction is never executed
.globl Exit0 Exit0: # end the program, default return status li $a0, 0 # return status 0 li $v0, 17 syscall jr $ra # this instruction is never executed
.globl Exit2 Exit2: # end the program, with return status from register $a0 li $v0, 17 syscall jr $ra # this instruction is never executed
# The following syscalls work on MARS, but not on QtSPIM
.globl Print_hex Print_hex: # print the integer in register $a0 (hexadecimal) li $v0, 34 syscall jr $ra
.globl Print_bin Print_bin: # print the integer in register $a0 (binary) li $v0, 35 syscall jr $ra
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started