# Arithmetic and Logic Instructions

In From C to Machine Instructions we examined the machine instructions produced for the executable file, and showed the disassembly listing and several diagnostic windows.

This example explores other logic operations (xor, or, and not) and how 32-bit constants are initialized using immediate (I-format) instructions having only 16-bit fields.

The basic MIPS arithmetic (addition and subtraction) and logic operations are listed below:

Instruction Description Function
AND Logical AND Rd = Rs & Rt
ANDI Logical AND Immediate Rt = Rs & Immed
NOR Logical NOR Rd = ~(Rs | Rt)
OR Logical OR Rd = Rs | Rt
ORI Logical OR Immediate Rt = Rs | Immed
SUB Integer Subtract Rt = (int)Rs - (int)Rd
SUBU Unsigned SubtractRt = (uns)Rs - (uns)Rd
XOR Exclusive OR Rd = Rs ^ Rt
XORI Exclusive OR Immediate Rt = Rs ^ (uns)Immed

## C Source

```01: #include <p32xxxx.h>
02:
03: int main()
04: {
05:         int na, nb, nc, nd;
06:
07:         na = 14;
08:         nb = na ^ 0x2ABCD87;
09:         nc = 0x1234ABCD;
10:         nd = na ^ nc;
11:         nb = na | nd;
12:         nc = (na + nb) - nc + 21;
13:         nd = ~na;
14:         return 0;
15: }
```

### Disassembly Listing

```---  C:\pic32\timer\calc\calc1.c  ----------------------------------------------------------------
1:                   #include
2:
3:                   int main()
4:                   {
9D00001C  AFBE0010   sw          s8,16(sp)
5:                   	int na, nb, nc, nd;
6:
7:                   	na = 14;
9D000028  AFC20000   sw          v0,0(s8)
8:                   	nb = na ^ 0x2ABCD87;
9D00002C  8FC30000   lw          v1,0(s8)
9D000030  3C0202AB   lui         v0,0x2ab
9D000034  3442CD87   ori         v0,v0,0xcd87
9D000038  00621026   xor         v0,v1,v0
9D00003C  AFC20004   sw          v0,4(s8)
9:                   	nc = 0x1234ABCD;
9D000040  3C021234   lui         v0,0x1234
9D000044  3442ABCD   ori         v0,v0,0xabcd
9D000048  AFC20008   sw          v0,8(s8)
10:                  	nd = na ^ nc;
9D00004C  8FC30000   lw          v1,0(s8)
9D000050  8FC20008   lw          v0,8(s8)
9D000054  00621026   xor         v0,v1,v0
9D000058  AFC2000C   sw          v0,12(s8)
11:                  	nb = na | nd;
9D00005C  8FC30000   lw          v1,0(s8)
9D000060  8FC2000C   lw          v0,12(s8)
9D000064  00621025   or          v0,v1,v0
9D000068  AFC20004   sw          v0,4(s8)
12:                  	nc = (na + nb) - nc + 21;
9D00006C  8FC30000   lw          v1,0(s8)
9D000070  8FC20004   lw          v0,4(s8)
9D000078  8FC20008   lw          v0,8(s8)
9D00007C  00621023   subu        v0,v1,v0
9D000084  AFC20008   sw          v0,8(s8)
13:                  	nd = ~na;
9D000088  8FC20000   lw          v0,0(s8)
9D00008C  00021027   nor         v0,zero,v0
9D000090  AFC2000C   sw          v0,12(s8)
14:                  	return 0;
15:                  }
9D00009C  8FBE0010   lw          s8,16(sp)
9D0000A4  03E00008   jr          ra
9D0000A8  00000000   nop
```

## Observations

Here the compiler is required to load an immediate operand larger than the 16-bit signed immediate field.

```8:                   	nb = na ^ 0x2ABCD87;
lw          v1,0(s8)        v1 <= na

lui         v0,0x2ab        v0 <= 0x2ABCD87
ori         v0,v0,0xcd87
```

Note that two instructions are required to load an immediate operand larger than can fit into a 16-bit range.

```   xor         v0,v1,v0        v0 <= v1 ^ v0
sw          v0,4(s8)        M[s8+4] <= v0
```

Here the compiler is asked to do a logical not (1's complement) operation. Note the use of the nor instruction.

```13:                  	nd = ~na;
lw          v0,0(s8)       v0 <= M[s8]
nor         v0,zero,v0     v0 <= ~(v0 | zero)
sw          v0,12(s8)      M[s8+12] <= v0
```

Maintained by John Loomis, updated Mon Aug 04 21:35:55 2008