 This time, we're going to be looking at some of the arithmetic operations that the MIPS architecture provides for us. You can see a list of our instructions over here, but all of these are integer operations. We will look at floating point operations later on, but it turns out we can get a whole lot of stuff done with just integer operations. And for the most part, these are the sort of operations you'd expect. We've got add, subtract, multiply, divide, but we've got a few other things in there. And some of these operations also have some odd features to them. So our first instruction there, the add instruction, takes the data from two registers, adds it together, and then stores the result into a third register. The add immediate instruction is slightly different in that it only takes one source from a register. The other source is given as a constant that's actually in the instruction itself. This is useful when you have a number that you know and you want to add that to a number that's in a register. The most obvious example is just say incrementing a counter, take our counter, we add one to it, we store it back into that counter again. Our subtract instructions like that first add instruction takes two registers as parameters, subtracts the data in one from the other, and stores the result in a third register. Multiply and divide are a little different. If I multiply two 32 bit numbers together, I can come out with something that's up to 64 bits long. Since all I have are 32 bit registers to work with, I can't really just assign that to a register directly. It can only hold 32 of the 64 bits that I could have. So instead the multiply instruction will perform the multiplication, and then it will take those results and we'll put the most significant 32 bits in the high register and the least significant 32 bits in the low register. Then we can use those move from high and move from low instructions to copy that data out of whichever register we're interested in into someplace where we can actually use them. So aside from using the move from high and move from low instructions, we won't be able to access the high and low registers, so we won't be able to do any further arithmetic on them or anything else we might be interested in. So once we're done with our multiply instruction, we'd always want to move data out of there. Since our divide instruction will be processing integer division, we will end up with two parts. We'll have a quotient and a remainder. The quotient will go into the low register and the remainder will go into the high register. Again, we've got two potential results, each of which could be 32 bits. So we'll have one 32-bit register for each of those, and then we'll just take out whichever piece we're actually interested in. Most of these instructions also have unsigned variants, for example, add unsigned, which will do same operation, but it won't be looking for any sort of overflow. So if you have some problem where you'd like to just ignore any potential overflow that you have, then you would want to use the unsigned operations instead. Those will be all of the actual instructions that the architecture provides for us. On the other hand, our assembler may give us some extra instructions that will make our lives a little easier. For example, the MUL pseudo instruction differs from the MULT instruction in that it will copy the results from the low register into an output register. In this case, it will just discard the upper 32 bits of the result and only keep the lower 32 bits. But if you're just multiplying small numbers and expecting to get a small number out, that can save you some time. Then you only have to write the MUL pseudo instruction. You don't have to write the MULT instruction followed by a move from low instruction. The DIV pseudo instruction is similar. It's going to do the integer division, and it will take the quotient from the low register and store that into an output register for you. On the other hand, the remainder pseudo instruction would do the integer division and then take the remainder from the high register and store it into an output. That can be useful in those cases where you're only interested in either the quotient or the remainder. If you're interested in both of them, you probably still want to use the regular DIV instruction and then just follow that up with a move from high and a move from low. The MUL pseudo instruction is a simple way to copy data from one register to another. Contrary to what you might expect from that name, it's not actually going to erase the original register. It's just going to copy that data from the source register to the destination register. The low to immediate pseudo instruction is also a simple way of just putting some number into a register for you. Anytime you put one of these pseudo instructions into your code, the machine doesn't actually know how to interpret this instruction. So these are actually instructions for the assembler, and the assembler will take them, translate them into one, two, or three instructions, and provide those real instructions to the CPU instead. This is where it would use the assembler temporary register as well.