Week 05 Tutorial Answers

  1. Often when writing large MIPS programs, you will make accidental errors that cause your program to misbehave.

    Discuss what tools are available to help debug broken MIPS code.

  2. Translate the following do-while loop to MIPS assembly.

    #include <stdio.h>
    
    int main(void) {
    	int i = 0;
    
    	do {
    		i++;
    
    		printf("%d", i);
    		printf("\n");
    	} while (i < 10);
    
    	return 0;
    }
    
  3. If the data segment of a particular MIPS program starts at the address 0x10000020, then what addresses are the following labels associated with, and what value is stored in each 4-byte memory cell?

        .data
    a:  .word   42
    b:  .space  4
    c:  .asciiz "abcde"
        .align  2
    d:  .byte   1, 2, 3, 4
    e:  .word   1, 2, 3, 4
    f:  .space  1
    
  4. Give MIPS directives to represent the following variables:

    1. int u;
    2. int v = 42;
    3. char w;
    4. char x = 'a';
    5. double y;
    6. int z[20];

    Assume that we are placing the variables in memory, at an appropriately-aligned address, and with a label which is the same as the C variable name.

  5. Consider the following memory state:

    Address       Data Definition
    0x10010000    aa:  .word 42
    0x10010004    bb:  .word 666
    0x10010008    cc:  .word 1
    0x1001000C         .word 3
    0x10010010         .word 5
    0x10010014         .word 7
    

    What address will be calculated, and what value will be loaded into register $t0, after each of the following statements (or pairs of statements)?

    1. la   $t0, aa
      
    2. lw   $t0, bb
      
    3. lb   $t0, bb
      
    4. lw   $t0, aa+4
      
    5. la   $t1, cc
      lw   $t0, ($t1)
      
    6. la   $t1, cc
      lw   $t0, 8($t1)
      
    7. li   $t1, 8
      lw   $t0, cc($t1)
      
    8. la   $t1, cc
      lw   $t0, 2($t1)
      
  6. What is a breakpoint?

    When is it useful in debugging?

  7. Translate this C program to MIPS assembler
    #include <stdio.h>
    
    int main(void) {
        int i;
        int numbers[10] = {0};
    
        i = 0;
        while (i < 10) {
            scanf("%d", &numbers[i]);
            i++;
        }
    }
    
  8. Translate this C program to MIPS assembler
    #include <stdio.h>
    
    int main(void) {
        int i;
        int numbers[10] = {0,1,2,3,4,5,6,7,8,9};
    
        i = 0;
        while (i < 10) {
            printf("%d\n", numbers[i]);
            i++;
        }
    }
    
  9. Translate this C program to MIPS assembler
    int main(void) {
        int i;
        int numbers[10] = {0,1,2,-3,4,-5,6,-7,8,9};
    
        i = 0;
        while (i < 10) {
            if (numbers[i] < 0) {
                numbers[i] += 42;
            }
            i++;
        }
    }
    
  10. Translate this C program to MIPS assembler
    #include <stdio.h>
    
    int main(void) {
        int i;
        int numbers[10] = {0,1,2,3,4,5,6,7,8,9};
    
        i = 0;
        while (i < 5) {
            int x = numbers[i];
            int y = numbers[9 - i];
            numbers[i] = y;
            numbers[9 - i] = x;
            i++;
        }
    }
    
  11. The following loop determines the length of a string, a '\0'-terminated character array:

    char *string = "....";
    char *s = &string[0];
    int   length = 0;
    while (*s != '\0') {
       length++;  // increment length
       s++;       // move to next char
    }
    

    Write MIPS assembly to implement this loop.

    Assume that the variable string is implemented like:

       .data
    string:
       .asciiz  "...."
    

    Assume that the variable s is implemented as register $t0, and variable length is implemented as register $t1. And, assume that the character '\0' can be represented by a value of zero.

  12. Conceptually, the MIPS pseudo-instruction to load an address could be encoded as something like the following:

    Since addresses in MIPS are 32-bits long, how can this instruction load an address that references the data area, such as 0x10010020?

  13. Implement the following C code in MIPS assembly instructions, assuming that the variables x and y are defined as global variables (within the .data region of memory):

    long x;     // assume 8 bytes
    int  y;     // assume 4 bytes
    
    scanf("%d", &y);
    
    x = (y + 2000) * (y + 3000);
    

    Assume that the product might require more than 32 bits to store.

  14. Write MIPS assembly to evaluate the following C expression, leaving the result in register $v0.

    ((x*x + y*y) - x*y) * z
    

    Write one version that minimises the number of instructions, and another version that minimises the number of registers used (without using temporary memory locations).

    Assume that: all variables are in labelled locations in the .data segment; the labels are the same as the C variable names; all results fit in a 32-bit register (i.e., no need to explicitly use Hi and Lo).

  15. Translate this C program to MIPS assembler.
    #include <stdio.h>
    
    char flag[6][12] = {
        {'#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'},
        {'#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'},
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'},
        {'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'},
        {'#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'},
        {'#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'}
    };
    
    int main(void) {
        for (int row = 0; row < 6; row++) {
            for (int col = 0; col < 12; col++)
                printf ("%c", flag[row][col]);
            printf ("\n");
        }
    
    }
    
  16. Consider the following operation that multiplies all of the elements in a matrix by a constant factor:

    This operation could be rendered in C99-standard C as

    void change (int nrows, int ncols, int M[nrows][ncols], int factor)
    {
        for (int row = 0; row < nrows; row++) {
            for (int col = 0; col < ncols; col++) {
                M[row][col] = factor * M[row][col];
            }
        }
    }
    

    Write a function in MIPS assembly equivalent to the above C code. Assume that the arguments are placed in the $a? registers in the order given in the function definition. e.g., the function could be called as follows in MIPS:

       li   $a0, 3
       li   $a1, 4
       la   $a2, M
       li   $a3, 2
       jal  change
    

    Where M is defined as:

        .data
    M:  .word 1, 2, 3, 4
        .word 3, 4, 5, 6
        .word 5, 6, 7, 8