Week 04 Tutorial Questions

Objectives

Code Review

A volunteer will be selected to present their sixteen_out.c code. The reviewee should give a brief description of their code, and the class should ask questions, comment on the quality of the code, and suggest improvements. Each review should take about 10 minutes.

Note: The Code Review will take place in the second hour of the tutorials for the week.


Questions

  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. 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
    
  3. 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.

  4. 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)
      
  5. Translate this C program to MIPS assembler
    // A simple program that will read 10 numbers into an array
    
    #define N_SIZE 10
    
    #include <stdio.h>
    
    int main(void) {
        int i;
        int numbers[N_SIZE] = {0};
    
        i = 0;
        while (i < N_SIZE) {
            scanf("%d", &numbers[i]);
            i++;
        }
    }
    
  6. Translate this C program to MIPS assembler
    // A simple program that will print 10 numbers from an array
    
    #define N_SIZE 10
    
    #include <stdio.h>
    
    int main(void) {
        int i;
        int numbers[N_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
        i = 0;
        while (i < N_SIZE) {
            printf("%d\n", numbers[i]);
            i++;
        }
    }
    
  7. Translate this C program to MIPS assembler
    // A simple program that adds 42 to each element of an array
    
    #define N_SIZE 10
    
    int main(void) {
        int i;
        int numbers[N_SIZE] = {0, 1, 2, -3, 4, -5, 6, -7, 8, 9};
    
        i = 0;
        while (i < N_SIZE) {
            if (numbers[i] < 0) {
                numbers[i] += 42;
            }
            i++;
        }
    }
    
  8. Translate this C program to MIPS assembler
    // A short program that reverses an array by swapping elements.
    
    #define N_SIZE 10
    #define N_SIZE_M_1 N_SIZE - 1
    #define N_SIZE_D_2 N_SIZE / 2
    
    #include <stdio.h>
    
    int main(void) {
        int i;
        int numbers[N_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
        i = 0;
        while (i < N_SIZE_D_2) {
            int x = numbers[i];
            int y = numbers[N_SIZE_M_1 - i];
    
            numbers[i] = y;
            numbers[N_SIZE_M_1 - i] = x;
    
            i++;
        }
    }
    
  9. 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.

  10. If we execute the following small MIPS program:

       .data
    x: .space 4
       .text
       .globl main
    main:
       li  $a0, 32768
       li  $v0, 1
       syscall
       sw  $a0, x
       lh  $a0, x
       li  $v0, 1
       syscall
       jr  $ra
    

    ... we observed that the first syscall displays 32768, but the second syscall displays -32768. Why does this happen?

  11. 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?

  12. 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.

    Hint: look up instructions mult, mfhi and mflo

Revision questions

The following questions are primarily intended for revision, either this week or later in session.
Your tutor may still choose to cover some of these questions, time permitting.

  1. Write a MIPS program that is equivalent to the following c program

    int main(void) {
        int x;
     
        scanf("%d", &x);
    
        printf("%d has ", x);
        if (x < 10 && x > -10) {
            printf("1 digit");
        }
        if ((x >= 10 && x < 100) || (x <= -10 && x > -100)) {
            printf("2 digits");
        }
        if (x >= 100 || x <= -100) {
            printf("more than 2 digits");
        }
        printf("\n");
    
        return 0;
    }