The result of multiplication is stored in two different registers in mips high and low.
For Example: in this example i take high and low as 4 bit register for the sake of convenience.
li $t0,12
mult $t0,$t0
12 * 12 = 144
1100 * 1100 = 1001 0000
so the high has 1001 and low has 0000. now if i want to subtract 12 from the result. how do i do that?
i cant use
mflo $t1
subi $t2,$t1,12
because low has all zeros and the result would be wrong.How do i perform subtraction in this case.when two numbers are 32 bit integers and multiplication causes an overflow.say something like
2^30 * 2^4 - 14
the high register is used.
MIPS registers are 32-bit (or 64-bit, but that does not change results in this case), so after multiplication you will have hi=0x00000000 and lo=0x00000090. I.e. the 8 bits of product fit into 32 bits of lo just fine.
After subtracting 12 from 0x90 you should expect to see t2=0x84
Related
I am learning about Computer architecture through the MIPS instructions. I have a question which is:
Memory at 0x10000000 contains 0x80
Register $5 contains 0x10000000
What is put in register $8 after lb $8,0($5) is executed?
I was thinking when the load byte is called, it will take the 8 bits of 0x80[10000000] from the 0x10000000 address and load it into the first 8 bits of the $8 register and fill the remaining bits with zeros making the answer to be 00000080. But the correct answer listed is FFFFFF80. I am not sure if I understand it. Can anybody help explain it?
The instruction you mention here is lb which loads a one byte into a register by sign-extending the byte to the word size. This means if the most significant bit is set to 1 it will fill the remaining 24 bits with 1 as well. This is done to preserve the twos-complement value of the byte in a 32 bit representation.
If your byte would be 0100 1010 the sign-extend would fill it with 0 as
0000 000... 0100 1010.
If your byte would be 1011 0101 the sign-extend would fill it with 1 as
1111 111... 1011 0101.
To avoid this and always pad the byte with 0 you can use the alternative lbu instruction which does not perform a sign-extend but pads the byte with 0 instead.
This preserves the unsigned value of the byte since twos-complement is not involved for those.
In MIPS, the opcodes for registers is 5 bits long.
I read that each register is 32 bits long, so why are only 5 used to represent their opcodes in the instruction format?
http://www.cs.uwm.edu/classes/cs315/Bacon/Lecture/HTML/ch05s03.html
"For example, the MIPS processor has 32 general-purpose registers, so it takes 5 bits to specify which one to use. In contrast, the MIPS has a 4 gibibyte memory capacity, so it takes 32 bits to specify which memory cell to use. An instruction with 3 operands will require 15 bits if they are all registers, and 96 bits if they are all memory addresses."
Compute all things in base 2.
You can address up to 4GiB of RAM with only 32 bits, right? This is because 2^32 gives you 4'294'967'296, which is the amount of independent "cells" you can access. Each of those "cells" are 8 bits (a byte).
The same thing happens with registers, except that each "cell" is 32 bits rather than 8 bits. With 5 bits for addressing registers, you get 2^5 = 32 possible cells - i.e. 32 possible registers of 32 bits.
The capacity of a register is not related to the quantity of bits you need to address a certain amount of registers.
I am currently using SPIM (QTSpim) to learn about MIPS. I had a few questions regarding the SPIM commands and how they work.
1) As far as I know, MIPS usually uses 16 bits to display values, but why do the registers in QTSpim only have 8 bits?
2) For register $11(t3), the original value was 10. After the machine performs a [sra $11, $11, 2] instruction, the value changes from 10 to 4. How does this happen? How are 2 positions shifted right when 10 is only 2 bits?
Thank you.
1) Not sure where you got that idea. QtSpim simulates a MIPS32-based machine, so the general-purpose registers are 32-bit.
2) 10 hexadecimal is 10000 binary. Shift that right by two and you get 100 binary, which is 4 decimal. You can also think of it as 16 decimal divided by 4, since sra by N bits is a (signed) division by 2^N.
Assuming that the current PC is 0x00400010 (after increment) and the target label has the value of 0x00400040. What is the binary value of the constant in the instruction?
beq $s0, $s0, target
I'm not really sure how to approach this question. I would appreciate a hint, or explanation of how to find a solution to this.
I am not sure if I have understood your question. I am assuming that you are asking for the offset which will be coded into the instruction.
Since the target is at 0x00400040 and the current PC is at 0x00400010, the offset probably will be 0x00000030 (because 0x00400040 - 0x00400010 = 0x00000030). This can be easily converted into the binary format you asked for:
0000 0000 0000 0000 0000 0000 0011 0000
But please note that I don't know MIPS. In some processor architectures, the offset coded into the instruction is
(target PC) - ((current PC) + (size of current instruction))
Since I don't know MIPS, I don't know what the byte size of the beq instruction is. Thus, I can't compute the offset for this case. If you tell me the size of the beq instruction, I'll make an edit to that answer and add that.
Furthermore, in most processor architectures, relative offsets will be restricted for most instructions. Once again, I don't know MIPS, but chances are that the offset is limited to 16, 12 or even 8 bits. In that case, to get the actual binary offset representation, remove zeroes from the left from the binary number I gave above until only the bits which are used to store the offset are left.
EDIT (taking into account Busy Beaver's comment)
On MIPS, it seems that instructions are aligned to 32 bits / 4 bytes. This allows to store the actual offset needed divided by 4 (the CPU then reads the offset and multiplies it by 4 to compute the actual target). The advantage is that you can store bigger offsets with the bits given. In other words, you save 2 offset bits that way.
In your example, the PC should jump by 0x00000030 bytes to get to the target. The offset stored in the instruction then would be 0x00000030 / 4 which is the same as 0x00000030 >> 2 which is 0x0000000C0. You asked for the binary representation:
0000 0000 0000 0000 0000 0000 0000 1100
When decoding / executing the instruction, the CPU automatically multiplies that offset by four and that way gets back the real offset desired.
I need to convert this jump to binary and I can't figure out how to get the immediate value. I tried doing it by taking the base address of the Loop which was assumed to be 40000 then divide it by 4 (40000 / 4 = 10000) but I don't know if this is correct (That was just how they did it in an example in my book).
Loop: slt $t0,$s0,$s1
beq $t0,1,Exit
sub $s0,$s0,$s1;
j Loop;
Exit:
Bits 25..0 of the j instruction become bits 27..2 of the PC and bits 1..0 become 00 (this is the divide by 4 business). This works because addresses are always 4-byte aligned.
So if Loop is at address 40,000 then the bottom 26 bits of the instruction are 00 0000 0000 0010 0111 0001 0000 (10,000) and the other 6 bits are the j opcode (0000 10).
When the instruction executes the value (10,000 in your case) is extracted and shifted left 2 bits (which is multiplying by 4). Then this value replaces the bottom 28 bits of the PC -- the top 4 bits (0000 in your case) remain unchanged. The next instruction your program executes will be at address 40,000.