# CSCI 255 — Chapter 6 miscellany

## The PowerPoint

Let’s take a look at addressing modes at slide 105.

## The MIPS instruction set

### The sometimes missing multiply

You won’t find the `mul` instruction in Wikipedia page on the MIPS instruction set. In the original MIPS instruction set there was an instruction called `mult` which stored the result of adding two 32-bit integers into a special register pair, `HI` and `LO`. If you wanted to multiply the registers `\$t4` and `\$t5` and store the result in `\$t6`, you used the following two instruction sequence:
`mult   \$t3,\$t4`
`mflo   \$t6`
There was also a restriction in the architecture that no multiply or divide instruction could be issued in the two instructions following the `mflo`.

### Assembly idioms

Assembly idioms, or pseudo instructions, looks like assembly language instructions, but are actually translated into sequences of one or more machine instructions.

Many of the assembly idioms provided the MIPS assembly language with “machine instructions” that were common on other computers. For example
`move   \$t8,\$t9`
is translated to
`addu   \$t8,\$t9,\$0`
`li     \$t3,1000`
is translated to
`addi   \$t3,\$0,1000`

A few assembly idioms translate to multiple machine instructions. For example
`mul    \$t8,\$t9,3`
is translated to
`addi   \$at,\$0,3`
`mul    \$t8,\$t9,\$at`
To provide a 32-bit load immediate,
`li     \$t3,10000000`
is translated to
`lui    \$t3,\$0,15`
`ori    \$t3,16960`
This works because `15` is `(1000000 >> 16) & 0xFFFF` and `16960` is `1000000 & 0xFFFF`.

## Big vs little endian

Take a look at the following references to see how the big vs little endian divide impacts network programming.

## Size of integer data types

The careful programmer includes stidin.h and uses types with names like `intN_t` and `uintN_t`. The integer data types of the XC32 compiler are found on page 144 of the MPLAB® XC32 C/C++ Compiler User’s Guide. Note that both the `int` and `long` are 32 bits. This was not the case with the Arduino.

## Arrays and structures

The textbook covers array in Section 6.4.5, after the discussion of control structures; but CSCI 255 will do arrays first!

### Finding the location of an array element

`cType X[] ;`
The address of `X[i]` can be computed as Base(`X`) + `i`×Size(`cType`). Because the sizes of most C data types are a multiple of two, shifts are usually used in place of multiplication.

Try to determine the appropriate code for implemented the following C program sequence.

```int V[15], i ;
V[3] = 17 ;
V[i] = V[i+3] ;
```

C stores arrays in row-major order. This significantly complicates determining the address of elements in multi-dimensional arrays. This time start with the declaration of a two-dimensional array:
`cType M[R][C] ;`
The address of `M[i][j]` can be computed as Base(`M`) + `i`×R×Size(`cType`) + `j`×Size(`cType`).

By the way, once these formulas were taught in the second programming course. However, Java does things a different way.

Here’s a harder one. Figure out the assembly code to implement the following C code.

```int I[100][100], r ;
I[17][20] = 5 ;
I[r][r] = 1 ;
```

### Finding the location of a structure member

This should be easier. Just find the offset of the member from the beginning of a structure, which should be a constant number, and then add it to the base.

In practice, this can be harder. Although members must be stored in the order they are listed in the structure definition, the padding between elements is implementation-defined. Consider the following structure definition.

```struct noteInfo {
int frequency ;
long duration ;
} ;
```

If `long` variables must be aligned on addresses divisible by 8, the offset to `duration` would be 8. Otherwise, it would be 4. You’d need to write a section of C code similar to the following to figure how this works on your favorite compiler.

```struct noteInfo sillyNote ;
long offset = (void *) &sillyNote - (void *)&sillyNote.duration ;
printf("Offset to duration is %ld\n", offset) ;
```

### Pointers

Pointers are easy because the pointer already contains the base address. Just add in the appropriate offset. Remember: `V[i]` is the same as `*(V+i)`.

### Getting down the details

It can be challenging for inexperienced assembler programmers to implement arrays operations correctly. The first thing you have to do is get the address of `V[i]` which is `V+i`.

Assume register that `\$tv` already contains `V`, the address of the `V[0]` and `\$ti` already contains `i`. In the case, if `V` is an array of integers, the code to store the address of `V[i]` into `\$tx` would be something like the following:

```        sll    \$tx,\$ti,2        # multiply i by 4 to obtain offset
```

Once you have the address, you can use `lw` to read from the array and `sw` to write to the array. An assignment state such as `U[i] = V[j]` could be implemented with something like the following:

```        la     \$t0,V
lw     \$t1,j
sll    \$t1,\$t1,2
add    \$t1,\$t1,\$t0     # \$t1 is &V[j]
lw     \$t2,0(\$t1)      # \$t2 is V[j]
la     \$t0,U
lw     \$t1,i
sll    \$t1,\$t1,2
add    \$t1,\$t1,\$t0     # \$t1 is &U[i]
sw     \$t2,0(\$t1)      # U[i] set to V[j]

```

## Control flow

First follow the rules of the Translating C to C: Control Structures page. The unconditional `goto` can be implemented with a single `j` (jump) instruction.

A conditional `goto` such as
`if (\$ti) goto λ`
where `\$ti` is a MIPS register containing the value of a C expression, can be implemented as:
`bne   \$ti,\$0,λ`

### Comparison and relational operators

However, the translation of the C comparison and relational operators remain. The MIPS `slt` instructions combined with the bitwise instructions would be sufficient for doing all of this. That is left as an exercise for the reader.

However, be careful! Is `x <= y` if and only if `x < y+1`? Is `x < y` if and only if `x-y < 0`?

### Logical operators

The `!` operator is easy, but the `&&` and `||` binary operators and the `? :` ternary conditional can short circuit and must be implemented with some form of the `if` as shown in the following table.

 `τ = exp1 && exp2 ;` `````` if (! (exp1)) τ = 0 ; else if (! (exp2)) τ = 0 ; else τ = 1 ; ``` ``` `τ = exp1 || exp2 ;` ```if (exp1) τ = 1 ; else if (exp2) τ = 1 ; else τ = 0 ; ``` `τ = exp1 ? exp2 : exp3 ;` `````` if (exp1) τ = exp2 ; else τ = exp3 ; ``` ```

### The real world

However, both compilers and humans can do much better than these inflexible rules.