Computer Systems Fundamentals

 Label Size     Content      Address       Instructions
    w:    .word    0x00010101   0x10000000    * la  $t0, w
    x:    .word    0x00008000   0x10000004    * lw  $t0, w
    y:    .byte    0x00000061   0x10000008    * lh  $t0, w
    z:    .byte    0x00000062   0x10000009    * lh  $t0, x
                                              * lhu $t0, x
                                              * lbu $t0, x
                                              * lb  $t0, z
                                              * lw  $t0, z
                                              * lw  $t0, y

la  $t0, w   $t0 = 0x10000000   #like &w
lw  $t0, w   $t0 = 0x00010101   #like w
lh  $t0, w   $t0 = 0x00000101   0000000100000001  +ve
lh  $t0, x   $t0 = 0xFFFF8000   1000000000000000  -ve
lhu $t0, x   $t0 = 0x00008000
lbu $t0, x   $t0 = 0x00000000
lb  $t0, z   $t0 = 0x00000062
lw  $t0, z   $t0 = ??????????  crash. alignment error
lw  $t0, y   $t0 = 0x00006261

                                      
                     
   Label Address      Content         Instructions
    x:    0x10010000   0x00010101    * la $t0, x
    y:    0x10010004   0x10010000    * lw $t0, x
    z:    0x10010008   0x0000002A      la $s0, z
    eol:  0x1001000C   0x0000000A    * lw $t0, ($s0)
                                       li $s0, 8
                                     * lw $t0, y($s0)
                                       lw $s0, y
                                     * lw $t0  ($s0)
                                       li $s0, 4
                                     * lw $t0, x+4($s0)
                                     
                                     
la $t0, x         $t0 = 0x10010000   #&x
lw $t0, x         $t0 = 0x00010101   #x
la $s0, z         $s0 = 0x10010008
lw $t0, ($s0)     $t0 = 0x0000002A 
li $s0, 8         $s0 = 8
lw $t0, y($s0)    $t0 = 0x0000000A
lw $s0, y         $s0 = 0x10010000
lw $t0, ($s0)     $t0 = 0x00010101
li $s0, 4         $s0 = 4
lw $t0, x+4($s0)  $t0 = 0x0000002A

0x10010000+4+4 = 0x10010008
demonstrate implementation of pointers by an address
#include <stdio.h>

int answer = 42;

int main(void) {
    int i;
    int *p;

    p = &answer;
    i = *p;
    // prints 42
    printf("%d\n", i); 
    *p = 27;
    // prints 27
    printf("%d\n", answer); 

    return 0;
}
demonstrate implementation of pointers by an address p in register $t0 i in register $t1 $t2 used for temporary value
main:
    la   $t0, answer # p = &answer;

    lw   $t1, ($t0)  # i = *p;

    move $a0, $t1    # printf("%d\n", i);
    li   $v0, 1
    syscall

    li   $a0, '\n'   # printf("%c", '\n');
    li   $v0, 11
    syscall

    li   $t2, 27     # *p = 27;
    sw   $t2, ($t0)  #

    lw   $a0, answer # printf("%d\n", answer);
    li   $v0, 1
    syscall

    li   $a0, '\n'   # printf("%c", '\n');
    li   $v0, 11
    syscall

    li   $v0, 0      # return 0 from function main
    jr   $ra         #


    .data
answer:
    .word 42         # int answer = 42;
print array of ints
#include <stdio.h>

int numbers[5] = { 3, 9, 27, 81, 243};

int main(void) {
    int i = 0;
    while (i < 5) {
        printf("%d\n", numbers[i]);
        i++;
    }
    return 0;
}
print array of ints
#include <stdio.h>

int numbers[5] = { 3, 9, 27, 81, 243};

int main(void) {
    int i = 0;
loop:
    if (i >= 5) goto end;
        printf("%d", numbers[i]);
        printf("%c", '\n');
        i++;
    goto loop;
end:
    return 0;
}
print array of ints i in $t0
main:
    li   $t0, 0          # int i = 0;
loop:
    bge  $t0, 5, end     # if (i >= 5) goto end;
    la   $t1, numbers    #    int j = numbers[i];
    mul  $t2, $t0, 4
    add  $t3, $t2, $t1
    lw   $a0, 0($t3)     #    printf("%d", j);
    li   $v0, 1
    syscall
    li   $a0, '\n'       #   printf("%c", '\n');
    li   $v0, 11
    syscall

    addi $t0, $t0, 1     #   i++
    b    loop            # goto loop
end:

    li   $v0, 0          # return 0
    jr   $ra

.data

numbers:                 # int numbers[10] = { 3, 9, 27, 81, 243};
     .word 3, 9, 27, 81, 243
read 10 numbers into an array then print the 10 numbers
#include <stdio.h>

int numbers[10] = { 0 };

int main(void) {
    int i = 0;
    while (i < 10) {
        printf("Enter a number: ");
        scanf("%d", &numbers[i]);
        i++;
    }
    i = 0;
    while (i < 10) {
        printf("%d\n", numbers[i]);
        i++;
    }
    return 0;
}
read 10 numbers into an array then print the 10 numbers
i in register $t0 registers $t1, $t2 & $t3 used to hold temporary results
main:

    li   $t0, 0         # i = 0
loop0:
    bge  $t0, 10, end0  # while (i < 10) {

    la   $a0, string0   #   printf("Enter a number: ");
    li   $v0, 4
    syscall

    li   $v0, 5         #   scanf("%d", &numbers[i]);
    syscall             #

    mul  $t1, $t0, 4    #   calculate &numbers[i]
    la   $t2, numbers   #
    add  $t3, $t1, $t2  #
    sw   $v0, ($t3)     #   store entered number in array

    addi $t0, $t0, 1    #   i++;
    b    loop0          # }
end0:

    li   $t0, 0          # i = 0
loop1:
    bge  $t0, 10, end1   # while (i < 10) {

    mul  $t1, $t0, 4     #   calculate &numbers[i]
    la   $t2, numbers    #
    add  $t3, $t1, $t2   #
    lw   $a0, ($t3)      #   load numbers[i] into $a0
    li   $v0, 1          #   printf("%d", numbers[i])
    syscall

    li   $a0, '\n'       #   printf("%c", '\n');
    li   $v0, 11
    syscall

    addi $t0, $t0, 1     #   i++
    b    loop1           # }
end1:

    li   $v0, 0          # return 0
    jr   $ra

.data

numbers:                # int numbers[10];
     .space 40

string0:
    .asciiz "Enter a number: "
read 10 integers then print them in reverse order
#include <stdio.h>

int numbers[10];

int main() {
    int count;

    count = 0;
    while (count < 10) {
        printf("Enter a number: ");
        scanf("%d", &numbers[count]);
        count++;
    }

    printf("Reverse order:\n");
    count = 9;
    while (count >= 0) {
        printf("%d\n", numbers[count]);
        count--;
    }

    return 0;
}
read 10 integers then print them in reverse order
count in register $t0 registers $t1 and $t2 used to hold temporary results
main:
    li   $t0, 0           # count = 0

read:
    bge  $t0, 10, print   # while (count < 10) {
    la   $a0, string0     # printf("Enter a number: ");
    li   $v0, 4
    syscall

    li   $v0, 5           #   scanf("%d", &numbers[count]);
    syscall               #
    mul  $t1, $t0, 4      #   calculate &numbers[count]
    la   $t2, numbers     #
    add  $t1, $t1, $t2    #
    sw   $v0, ($t1)       #   store entered number in array

    addi $t0, $t0, 1      #   count++;
    b    read             # }

print:
    la   $a0, string1     # printf("Reverse order:\n");
    li   $v0, 4
    syscall
    li   $t0, 9           # count = 9;
next:
    blt  $t0, 0, end1     # while (count >= 0) {

    mul  $t1, $t0, 4      #   printf("%d", numbers[count])
    la   $t2, numbers     #   calculate &numbers[count]
    add  $t1, $t1, $t2    #
    lw   $a0, ($t1)       #   load numbers[count] into $a0
    li   $v0, 1
    syscall

    li   $a0, '\n'        #   printf("%c", '\n');
    li   $v0, 11
    syscall

    addi $t0, $t0, -1     #   count--;
    b    next             # }
end1:

    li   $v0, 0           # return 0
    jr   $ra

.data

numbers:                 # int numbers[10];
     .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

string0:
    .asciiz "Enter a number: "
string1:
    .asciiz "Reverse order:\n"
#include <stdio.h>

int
main() {
    int i;
    int numbers[10];

    i = 0;
    while (i < 10) {
        printf("Enter a number: ");
        scanf("%d", &numbers[i]);
        i++;
    }
    i = 0;
    while (i < 10) {
        numbers[i] *= 42;
        i++;
    }
    i = 0;
    while (i < 10) {
        printf("%d\n", numbers[i]);
        i++;
    }
    return 0;
}
i in register $t0 registers $t1..$t3 used to hold calculations
main:
    li   $t0, 0           # i = 0

loop0:
    bge  $t0, 10, end0  # while (i < 10) {
    la   $a0, string0   # printf("Enter a number: ");
    li   $v0, 4
    syscall

    li   $v0, 5         # scanf("%d", &numbers[i]);
    syscall             #
    mul  $t1, $t0, 4    # calculate &numbers[i]
    la   $t2, numbers   #
    add  $t1, $t1, $t2  #
    sw   $v0, ($t1)     # store entered number in array

    addi $t0, $t0, 1    # i++;
    b    loop0
end0:
    li   $t0, 0         # i = 0

loop1:
    bge  $t0, 10, end1  # while (i < 10) {

    mul  $t1, $t0, 4    #
    la   $t2, numbers   # calculate &numbers[i]
    add  $t1, $t1, $t2  #
    lw   $t3, ($t1)     # load numbers[i] into $t3
    mul  $t3, $t3, 42   # numbers[i] *= 42;
    sw   $t3, ($t1)     # store scaled number in array

    addi $t0, $t0, 1    # i++;
    b    loop1
end1:
    li   $t0, 0

loop2:
    bge  $t0, 10, done  # while (i < 10) {

    mul  $t1, $t0, 4    # printf("%d", numbers[i])
    la   $t2, numbers   # calculate &numbers[i]
    add  $t1, $t1, $t2  #
    lw   $a0, ($t1)     # load numbers[i] into $a0
    li   $v0, 1
    syscall

    li   $a0, '\n'      # printf("%c", '\n');
    li   $v0, 11
    syscall

    addi $t0, $t0, 1    # i++
    b    loop2

done:
    li    $v0, 0        # return 0
    jr    $ra

.data

numbers:
    .space 40           # int numbers[10];

string0:
    .asciiz "Enter a number: "
print an array using pointers
#include <stdio.h>

int numbers[5] = { 3, 9, 27, 81, 243};

int main(void) {
    int *p = &numbers[0];
    int *q = &numbers[4];
    while (p <= q) {
        printf("%d\n", *p);
        p++;
    }
    return 0;
}
print an array using pointers
#include <stdio.h>

int numbers[5] = { 3, 9, 27, 81, 243};

int main(void) {
    int *p = &numbers[0];
    int *q = &numbers[4];
loop:
    if (p > q) goto end;
        int j = *p;
        printf("%d", j);
        printf("%c", '\n');
        p++;
    goto loop;
end:
    return 0;
}
print an array using pointers p in $t0, q in $t1
main:
    la   $t0, numbers    # int *p = &numbers[0];
    la   $t0, numbers    # int *q = &numbers[4];
    addi $t1, $t0, 16    #
loop:
    bgt  $t0, $t1, end   # if (p > q) goto end;
    lw   $a0, 0($t0)     # int j = *p;
    li   $v0, 1
    syscall
    li   $a0, '\n'       #   printf("%c", '\n');
    li   $v0, 11
    syscall

    addi $t0, $t0, 4     #   p++
    b    loop            # goto loop
end:

    li   $v0, 0          # return 0
    jr   $ra

.data

numbers:                 # int numbers[10] = { 3, 9, 27, 81, 243};
     .word 3, 9, 27, 81, 243
print a 2d array
#include <stdio.h>

int numbers[3][5] = {{3,9,27,81,243},{4,16,64,256,1024},{5,25,125,625,3125}};

int main(void) {
    int i = 0;
    while (i < 3) {
        int j = 0;
        while (j < 5) {
            printf("%d", numbers[i][j]);
            printf("%c", ' ');
            j++;
        }
        printf("%c", '\n');
        i++;
    }
    return 0;
}
print a 2d array
#include <stdio.h>

int numbers[3][5] = {{3,9,27,81,243},{4,16,64,256,1024},{5,25,125,625,3125}};

int main(void) {
    int i = 0;
loop1:
    if (i >= 3) goto end1;
        int j = 0;
    loop2:
        if (j >= 5) goto end2;
            printf("%d", numbers[i][j]);
            printf("%c", ' ');
            j++;
        goto loop2;
    end2:
        printf("%c", '\n');
        i++;
    goto loop1;
end1:
    return 0;
}
print a 2d array i in $t0 j in $t1 $t2..$t6 used for calculations
main:
    li   $t0, 0         # int i = 0;
loop1:
    bge  $t0, 3, end1   # if (i >= 3) goto end1;
    li   $t1, 0         #    int j = 0;
loop2:
    bge  $t1, 5, end2   #    if (j >= 5) goto end2;
    la   $t2, numbers   #        printf("%d", numbers[i][j]);
    mul  $t3, $t0, 20
    add  $t4, $t3, $t2
    mul  $t5, $t1, 4
    add  $t6, $t5, $t4
    lw   $a0, 0($t6)
    li   $v0, 1
    syscall
    li   $a0, ' '      #       printf("%c", ' ');
    li   $v0, 11
    syscall
    addi $t1, $t1, 1   #       j++;
    b    loop2         #    goto loop2;
end2:
    li   $a0, '\n'     #    printf("%c", '\n');
    li   $v0, 11
    syscall

    addi $t0, $t0, 1   #   i++
    b    loop1         # goto loop1
end1:

    li   $v0, 0        # return 0
    jr   $ra

.data
# int numbers[3][5] = {{3,9,27,81,243},{4,16,64,256,1024},{5,25,125,625,3125}};
numbers:
     .word  3, 9, 27, 81, 243, 4, 16, 64, 256, 1024, 5, 25, 125, 625, 3125

Simple Example of a struct with no padding


main:
    la      $t0, date
    li      $t1, 7
    sw      $t1, 0($t0)
       
    la      $t0, date
    li      $t1, 2
    sw      $t1, 4($t0) 
    
    la      $t0, date
    li      $t1, 2023
    sw      $t1, 8($t0)
    
    
    la      $t0, date
    lw      $a0, 0($t0)
    li      $v0, 1
    syscall
    
    la      $t0, date
    lw      $a0, 4($t0)
    li      $v0, 1
    syscall
    
    la      $t0, date
    lw      $a0, 8($t0)
    li      $v0, 1
    syscall
    
     
    li      $v0, 0
    jr      $ra

   .data
date:                   #Date d;
    .space  12          #typedef struct _Date {
			#   int  day;    #4 bytes
			#   int  month;  #4
			#   int year;    #4
			#} Date;         #Total 12 
 

A struct example requiring padding in the middle of the struct
main:
    la $t0, person
    li $t1, 'A'
    sb $t1, 0($t0)
    
    la $t0, person
    li $t1, 'F'
    sb $t1, 1($t0)
    
    la $t0, person
    li $t1, 21
    sw $t1, 4($t0)
    
    li $v0, 0
    jr $ra

   .data
person:         #Person person;
    .space  8   #typedef struct _Person {
                #   char firstInitial;     // 1    'A'
                #   char lastInitial;      // 1    'F'
                #                          // 2 bytes padding
                #   int  age;              // 4
                #} Person;                 // 8   

A struct example requiring padding at the end of the struct
               // 8   

main:

    la $t0, person
    li $t1, 21
    sw $t1, 0($t0) 

    la $t0, person
    li $t1, 'A'
    sb $t1, 4($t0)
    
    la $t0, person
    li $t1, 'F'
    sb $t1, 5($t0)
    
    la $t0, person2
    li $t1, 100
    sw $t1, 0($t0) 

    la $t0, person2
    li $t1, 'T'
    sb $t1, 4($t0)
    
    la $t0, person2
    li $t1, 'A'
    sb $t1, 5($t0)
    
    
    
    li $v0, 0
    jr $ra

   .data
person:                     #Person person;
    .space 8
person2:
    .space 8              
                            #typedef struct _Person {
                            #   int age;               // 4
                            #   char firstInitial;     // 1    
                            #   char lastInitial;      // 1    
                            #   padding                // 2
                            #} Person;  
access fields of a simple struct
#include <stdio.h>
#include <stdint.h>

struct details {
    uint16_t  postcode;
    char      first_name[7];
    uint32_t  zid;
};

struct details student = {2052, "Andrew", 5123456};

int main(void) {
    printf("%d", student.zid);
    putchar(' ');
    printf("%s", student.first_name);
    putchar(' ');
    printf("%d", student.postcode);
    putchar('\n');
    return 0;
}
struct details { uint16_t postcode; char first_name[7]; uint32_t zid; };
offset in bytes of fields of struct details
DETAILS_POSTCODE   = 0
DETAILS_FIRST_NAME = 2
DETAILS_ZID        = 9

main:
    la   $t0, student           # printf("%d", student.zid);
    add  $t1, $t0, DETAILS_ZID
    lw   $a0, ($t1)
    li   $v0, 1
    syscall

    li   $a0, ' '               #   putchar(' ');
    li   $v0, 11
    syscall

    la   $t0, student           # printf("%s", student.first_name);
    addi $a0, $t0, DETAILS_FIRST_NAME
    li   $v0, 4
    syscall

    li   $a0, ' '               #   putchar(' ');
    li   $v0, 11
    syscall

    la   $t0, student           # printf("%d", student.postcode);
    addi $t1, $t0, DETAILS_POSTCODE
    lhu  $a0, ($t1)
    li   $v0, 1
    syscall

    li   $a0, '\n'              #   putchar('\n');
    li   $v0, 11
    syscall

    li   $v0, 0                 # return 0
    jr   $ra

.data

student:                 # struct details student = {2052, "Alice", 5123456};
     .half 2052
     .asciiz "Andrew"
     .word 5123456
access fields of a simple struct
struct details { uint16_t postcode; char first_name[7]; uint32_t zid; };
offset in bytes of fields of struct details
DETAILS_POSTCODE   = 0
DETAILS_FIRST_NAME = 2
DETAILS_ZID        = 12

main:
    la   $t0, student           # printf("%d", student.zid);
    addi $t1, $t0, DETAILS_ZID
    lw   $a0, ($t1)
    li   $v0, 1
    syscall

    li   $a0, ' '               #   putchar(' ');
    li   $v0, 11
    syscall

    la   $t0, student           # printf("%s", student.first_name);
    addi $a0, $t0, DETAILS_FIRST_NAME
    li   $v0, 4
    syscall

    li   $a0, ' '               #   putchar(' ');
    li   $v0, 11
    syscall

    la   $t0, student           # printf("%d", student.postcode);
    addi $t1, $t0, DETAILS_POSTCODE
    lhu  $a0, ($t1)
    li   $v0, 1
    syscall

    li   $a0, '\n'              #   putchar('\n');
    li   $v0, 11
    syscall

    li   $v0, 0                 # return 0
    jr   $ra

.data

student:                 # struct details student = {2052, "Andrew", 5123456};
     .half 2052
     .asciiz "Andrew"
     .space 3            # struct padding to ensure zid field is ona 4-byte boundary
     .word 5123456