# EE 361 Homework 3

Due Date: 9/23/05 (fri)

Assignment:

Problem 1. (2 pts) Consider the following C functions:

`/*  Returns the minimum value of array a[], which has length "length" */minarry(int a[], int length){  int i, k;   k = a[0];   for (i=0; i<length; i++) k = min(k,a[i]);   return(k);}min(int i, int j){ if (i < j) return(i);  else return(j);}`

Write a MIPS assembly language implementation of the functions. You may assume that parameters are passed to the functions through registers \$a0 and \$a1, where \$a0 is the first parameter and \$a1 is the second. For the function "minarray", the first parameter is an address that points to the beginning of array a[].  You may use \$t0-\$t9 for temporary storage, as well as the stack. Also assume that all return parameters are passed through \$2.

Problem 2. (1 pt) Consider the following machine code of a program that starts at memory location 16. Disassemble the code giving an assembly language equivalent, complete with labels (you may use whatever names you want for your labels, e.g., "Skip:", "Loop:"). Note that the machine code is in "decimal representation", which shows the decimal values of each field.

`    +-----+-----+-----+-----+-----+-----+    |  8  |  0  |  3  |       4         |    +-----+-----+-----+-----+-----+-----+    |  5  |  0  |  3  |       3         |    +-----+-----+-----+-----+-----+-----+    |  0  |  2  |  3  |  1  |  0  | 34  |    +-----+-----+-----+-----+-----+-----+    |  8  |  3  |  3  |       -1        |    +-----+-----+-----+-----+-----+-----+    |  2  |           5                 |    +-----+-----+-----+-----+-----+-----+`

Problem 3. (2 pts)

For this part, you will be introduced to the MIPS simulator SPIM. The simulator will allow you to run MIPS assembly language programs. Read the instructions in Appendix A.9 (page A-38 to A-49) for SPIM.  Actually, the pages A-38 to A-43 are sufficient to get started.  You may also go over Appendix A.10 which describes the MIPS assembly language. This goes into detail about different instructions, pseudo instructions, and assembler directives.

For this problem, you will use a PC version of this simulator called PCSpim.  You can download a free copy to your own computer and find documentation about PCSpim by going to the following web site:  SPIM web site   The instructions in Appendix A.9 is for SPIM rather than PCSpim but they should be reasonably close to what you need to run PCSpim.  If you don't have your own computer, PCSpim is available on the EE PC Server on the PCs in Holmes 387.  Find a PC then go to "My Computer" -> "EE PC Server" -> Folder named "spim" -> "pcspim.exe".

Let's run an assembly language program.

`##  This program multiplies \$20 and \$21, and puts the product in \$22.#main:		move	\$22,\$0		# This initializes \$22 to zero.	move	\$23,\$20		# \$23 is a temp. reg., used as a counter.loop:		beq	\$0,\$23,quit	# if the counter is zero, then quit	add	\$22,\$22,\$21	# \$22 = \$22 + \$21	addi	\$23,\$23,-1	# \$23 = \$23 - 1 (update counter)				#     Note: "addi" is a new instruction	j 	loopquit:	jr	\$31`

First Run -- No Frills.

• Use the load control button to load test2.s. Note that the test2.s is loaded at address 0x00400020. The set of instructions that starts from 0x0040000 is some housekeeping to be done before executing to test2.s. These instructions are
`              lw \$4, 0(\$29)              addiu \$5, \$29, 4              addiu \$6, \$5, 4              sll \$2, \$4, 2              addu \$6, \$6, \$2              jal 0x00400020 [main]              nop`
• You may not be able to see all of test2.s in the Text Segment Panel (last instruction is jr \$31 at address 0x0040003c) but for PCSpim, there is a scroll bar on the right so you can adjust your view. (For the spim program running workstations, to make the Panel longer notice that there's a small black box in the lower right corner of the Panel. Put the cursor there. The cursor should now change to an icon having arrows pointing up and down. Click the left mouse button, and use the mouse to make the panel bigger until you see all of the program it should include the instruction jr \$31 at memory location 0x03e00008.)
• Initialize \$20 and \$21 to the values 3 and 4, respectively, using set value that can be found on the Simulator menu of PCSpim. You should see the values for \$21 and \$21 change in the simulator.
• Run the program using the Go (F5) in the Simulator menu. Note the default address of where to start running is 0x00400000 which is okay because we want to do the "housekeeping"
• When the program stops, check if \$22 has the product 3x4 = 12. In hexadecimal this is 0xc.

Second Run -- Single Stepping. This time we will use the single step feature.

• Initialize \$20 and \$21 to the values 3 and 4 respectively, by using the set value control button. (These registers may be initialized already.)
• Step through the instructions using the Single Step (F10) control in the Simulator menu. Every time you single step, an instruction is executed. By stepping through the instructions starting from 0x00400004, you can see how the "housekeeping instructions"

`              lw \$4, 0(\$29)              addiu \$5, \$29, 4              addiu \$6, \$5, 4              sll \$2, \$4, 2              addu \$6, \$6, \$2              jal 0x00400020 [main]`

Before the program is executed. Note that the loop of the program is executed three times, and the register values will change as the program is executed.

The program is completed after the jr \$31 instruction is executed, and we jump back to nop, which is one of the "housekeeping instructions".

Notice that we have the option of stepping through multiple instructions. Try this exercise again, but using multiple step sizes to see what happens.

Third Run -- Breakpoints. This time we will use breakpoints.

• Initialize \$20 and \$21 to the values 4 and 5, respectively, using the set value. Check to see that the values are properly loaded into the registers.
• Set a breakpoints at
• "main:" which is 0x00400024
• "loop:" which is 0x0040002c
• the instruction nop which is at 0x00400018
To set breakpoints, simply select Breakpoints (Ctrl+B), and add the breakpoint addresses.  You can also delete breakpoints by selecting the addresses and then remove.
• Run the program starting at the default address by selecing Go. (Notice the instructions at the breakpoints have been replaced by an instruction break \$1 . This is a special instruction recognized by the processor. Whenever the processor executes this instruction it goes to a special location to execute a program. This is called a "software interrupt" and the program is called an "interrupt handler". The interrupt handler determines the proper operation to be executed at the breakpoint, updates register values, etc accordingly.)
• You will hit the breakpoint at "main" which is 0x00400024.
• Continue running the program until you hit the breakpoint at "loop:".
• Question 1. What are the values in the registers \$20, \$21, \$22, and \$23?
• Continue running the program until you hit the breakpoint at "loop:" again.
• Question 2. What are the values in the registers \$20, \$21, \$22, and \$23?
• Keep continuing until you hit the breakpoint at 0x00400018.
• Question 3. What are the values in the registers \$20, \$21, \$22, and \$23?
Problem 4 (1 pt)

Consider the following C program

main()
{
int addall(int n0, int n1, int n2, int n3, int n4, int n5);
int i;

}

addall(int x0, int x1, int x2, int x3, int x4, int x5)
{
return x0+x1+x2+x3+x4+x5;
}

After compiling the program using mcc, we get the following assembly language program  (Note that "li" is a psuedo instruction and can be implemented by an "addi" instruction.  For example, "li    \$2,10" is to load register \$2 with the constant 10.  It can be implemented using "addi \$2,\$0,10".  You can find the description of "li" in Appendix A along with all the other assembly language instructions.  Also note that "addu" and "subu" is just like "add" and "sub" so for this exercise you can treat them as the same.)

.file    1 "test4.c"

# GNU C 2.5.7 [AL 1.1, MM 40] BSD Mips compiled by CC

# Cc1 defaults:

# Cc1 arguments (-G value = 8, Cpu = default, ISA = 1):
# -quiet -dumpbase -O -fno-delayed-branch

gcc2_compiled.:
__gnu_compiled_c:
.text
.align    2
.globl    main

.loc    1 2
.ent    main
main:
.frame    \$sp,32,\$31        # vars= 0, regs= 1/0, args= 24, extra= 0
subu    \$sp,\$sp,32
sw    \$31,24(\$sp)
li    \$2,0x0000000e        # 14
sw    \$2,16(\$sp)
li    \$2,0x0000000f        # 15
sw    \$2,20(\$sp)
li    \$4,0x0000000a        # 10
li    \$5,0x0000000b        # 11
li    \$6,0x0000000c        # 12
li    \$7,0x0000000d        # 13
lw    \$31,24(\$sp)
j    \$31
.end    main
.align    2

.loc    1 10
.frame    \$sp,0,\$31        # vars= 0, regs= 0/0, args= 0, extra= 0