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 |
---|---|---|
ADD | Integer Add | Rd = Rs + Rt |
ADDI | Integer Add Immediate | Rt = Rs + Immed |
ADDIU | Unsigned Integer Add Immediate | Rt = Rs +U Immed |
ADDU | Unsigned Integer Add | Rd = Rs +U Rt |
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 Subtract | Rt = (uns)Rs - (uns)Rd |
XOR | Exclusive OR | Rd = Rs ^ Rt |
XORI | Exclusive OR Immediate | Rt = Rs ^ (uns)Immed |
Source code: calc.zip
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: }
--- C:\pic32\timer\calc\calc1.c ---------------------------------------------------------------- 1: #include2: 3: int main() 4: { 9D000018 27BDFFE8 addiu sp,sp,-24 9D00001C AFBE0010 sw s8,16(sp) 9D000020 03A0F021 addu s8,sp,zero 5: int na, nb, nc, nd; 6: 7: na = 14; 9D000024 2402000E addiu v0,zero,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) 9D000074 00621821 addu v1,v1,v0 9D000078 8FC20008 lw v0,8(s8) 9D00007C 00621023 subu v0,v1,v0 9D000080 24420015 addiu v0,v0,21 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; 9D000094 00001021 addu v0,zero,zero 15: } 9D000098 03C0E821 addu sp,s8,zero 9D00009C 8FBE0010 lw s8,16(sp) 9D0000A0 27BD0018 addiu sp,sp,24 9D0000A4 03E00008 jr ra 9D0000A8 00000000 nop
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