Академический Документы
Профессиональный Документы
Культура Документы
Michael Le (cs61c-ta@imail.eecs.berkeley.edu)
Working with MIPS One significant difference between assembly language (i.e. MIPS) and high level languages like C is where work is done. In C, work is done with statements and variables keep track of the data. The equivalent things in assembly are instructions and registers. Unlike high level languages, assembly languages have a limited amount of registers and thus force the programmer to keep track of what each register contains and how it should be interpreted. This brings up the second significant difference between high level languages and assembly language: registers do not carry type as it is the instructions themselves that will give the register its type. That means that a single register can be interpreted as a signed integer at one point in the language, a character at another point, and a pointer in a third. The lack of types often causes students confusion because students are used to the fact that a variable holds one type of thing. Therefore, when a student accepts that registers can be of any type and that instructions dictate how a register will be interpreted irrelevant of how that register has been used in the past, the student is well on his/her way to understanding assembly language
The Power of MIPS All the instructions that are available in MIPS can be found on the green card of your COD book. If you do not have that, try to copy that sheet from your friend as it is a handy guide to the instructions (and a lot more) for the midterm/finals ;-). In the meantime, the last section of Appendix A has a list of all the instructions SPIM will understand and also provides brief descriptions of what each instruction will do. So, if you are in doubt of what an instruction does or what is available, Appendix A is where you want to go. As heads up for the midterm and final, all the instructions that are useful to you are on the green sheet and the use of some of the instructions in the Appendix A (i.e. the pseudoinstructions) are not recommended. Many MIPS related questions in the midterm/final will deal with most of the instructions on the green sheet so familiarizing yourself with those instructions is in your best interest.
The Meaning of Overflow Like many other things in CS, some things are poorly named or have different meanings in different contexts. In MIPS, the letter u is abused. Depending on the kind of instruction, it can take on one of
three different meanings. 1. arithmetic instructions a letter u with an arithmetic instruction means ignore overflow. This means if the true value was not achieved after the execution of the instruction, do not notify the program. 2. comparison instructions a letter u with a comparison instruction means compare the two values via unsigned. As you know, 0x80000000 and 0x00000000 generate two different results when compared signed and unsigned. 3. memory instructions -- a letter u with a memory instruction means do not sign-extend the most significant bit when retrieving values from memory. In MIPS, it is possible to read in only 1 or 2 bytes with a memory instruction. Since MIPS registers (in this class) are 32-bits, we have a choice of how to fill in the upper 24 and 16 bits respectively.
Mapping Between C and MIPS The following may be useful conversion patterns of C code and MIPS. Note it is not a comprehensive list of all patterns of C code you have seen but it should give you an idea of how things work. Arithmetic
i = j + k; i = j k; i = j + k + 4; add sub addi add sll sll $t0, $t1, $t2 $t0, $t1, $t2 $t0, $t2, 4 $t0, $t0, $t1 $t0, $t0, 2 $t0, $t0, 2 # i = j + k # i = j - k # i = k + 4 # i = i + j # i = i << 2 # i = i << 2
i = i << 2; i = i * 4;
If equals
if( a == b ) { // work #1 } else { // work #2 } bne $t0, $t1, else # work 1 j fin else: # work 2 fin: # a == b
If not equals
if( a != b ) { // work #1 } else { // work #2 } beq $t0, $t1, else # work 1 j fin else: # work 2 fin: # a != b
A[i]
A[i] = 4;
A few other constructs that I have not covered are switches, multi-dimensional arrays, and struct field referencing (. and ->). Each of these three constructs is built off of the ones you see above. So, a good exercise is to try to do a conversion yourself. In next discussion, we will go over an example of the MIPS behind switches, multi-dimensional arrays, and struct field referencing.
loop:
# i++
Note: A lot of these instructions are redundant and thus, this assembly code could be optimized. However, a blind conversion of C code will produce a result similar to this. Also, there is more than one way to do the same code. As an exercise, how could you do some things differently?
b) Explain the three different schemes of traversing the heaps free list?
Problem 2: Translating C to MIPS #1 Translate the following C code at right into MIPS. Assume a is in $s0 and b is in $s1.
beq $s0, $0, end addi $t0, $0, 5 bne $s1, $t0, end #insert code here end:
Problem 3: Translating C to MIPS #2 Translate the following C code below into MIPS. Assume i is in $s0, arr1 is in $s1, aar2 is in $s2, and len in $s3.
addi int int int int *arr1; *arr2; len; i; loop: # assume that len >= 0 for # this to work beq $s0, $s3, done # t1 = 4*i (we must do this # because ints are 4 bytes) add $t1, $t0, $t0 add $t1, $t1, $t1 add lw add sw addi j done: $t2, $t3, $t2, $t3, $s0, loop $s2, $t1 0($t2) $s1, $t1 $($t2) $s0, 1 $s0, $0, 0 #i = 0
/* some other code here which initializes the two arrays (i.e. presumably arr1 and arr2 aren't garbage) */ for (i = 0; i < len; i++) { arr1[i] = arr2[i]; }
Problem 4: Reverse Engineering MIPS In a sentence or two, explain what the following MIPS code does. Also, what kind of value must be in $t0 to allow the code to run?
# ptr loaded into $t0 andi $t1, $t0, 0x3 foo: bne $t1, $zero, end addi $t1, $t0, 12 loop: lw $t2, 0($t0) lw $t3, 0($t1) addi $t0, $t0, 4 addi $t1, $t1, -4 sw $t2, 4($t1) sw $t3, -4($t0) slt $t3, $t0, $t1 bne $t3, $zero, loop end:
This code swaps the endianess of a 64-bit integer. This code will only do the swap if the pointer is word aligned.