5

I have an exam coming up, and one of the practice problems was:

Assume that $t0 contains the value 0x12121212 and $t1 contains the address 0x1000000.

Assume that the memory data, starting from address 0x1000000 is: 88 77 66 55.

What will be the value of $t0 after the following code is executed:

lb $t0, 0($t1)

a) 0x00000088 b) 0x88121212 c) 0xffffff88 d) 0x12121288

The answer I gave was a, because the byte that the lb instruction will read (by my understanding of what the instruction does) is 88. The 88 will then be stored in $t0, thus the value will be 0x00000088. But the answer given was c. I feel like I have a fundamental misunderstanding about how lb works - can someone please explain why the answer is c?

Daniel
  • 2,944
  • 3
  • 22
  • 40

2 Answers2

9

The answer would be c) 0xffffff88. The lb instructions sign-extends the byte into a 32-bit value. I.e. the most significant bit (msb) is copied into the upper 24 bits.

0x88 == 0b10001000, i.e. the msb is 1. So the upper 24 bits will be 0b111111111111111111111111 == 0xffffff.

Michael
  • 57,169
  • 9
  • 80
  • 125
5

The lb instruction loads a byte from memory and sign extends to the size of the register. The lbu instruction does the same without sign extension (unsigned).

http://en.wikipedia.org/wiki/MIPS_architecture#Integer

Most computers, MIPS included, use two's complement to represent signed values though there are other ways to encode the sign, floating point is usually represented in IEEE 754 format which uses signed magnitude. An integer signed value can be represented in any number of bits, for example

  • a char in C is 8-bits and can represent -128 to +127
  • a short in C is 16-bits and can represent -32768 to +32767
  • etc

In two's complement the most significant bit can be used to determine the sign of the number, a '1' means it is negative, and a '0' means it is positive.

The number 0x88, when interpreted as an 8-bit two's complement number is negative 0x78 or -120 decimal. When represented in 32-bits two's complement this is 0xFFFFFF88. There are a couple of ways to remember how to compute the two's complement of a number:

  • take the one's complement of the number (invert every bit) and add '1', or
  • go from least significant bit towards most significant bit (right to left), skip over every '0' and the first '1' you encounter, invert every bit after that

To sign extend a 8-bit to 32-bits just look at the most significant bit (bit 7) and copy that bit to bits 8 thru 31... This follows from the definition of two's complement.

amdn
  • 11,314
  • 33
  • 45
  • Thanks, but this is just information I could have gotten off Wikipedia, and the same information written in my textbook - I still don't understand why the answer to the problem in my question is `c`. – Daniel Feb 12 '13 at 15:57
  • @Daniel, amdn told you your answer and even highlighted the relevant part. You should read up on sign extension. – Carl Norum Feb 12 '13 at 15:58
  • @CarlNorum Maybe my title is misleading, but I didn't think "Why is the answer c?" to be an appropriate title, though it is my actual question. I suspected sign extension as well (the preceding `0xffffff` was clear enough) but I don't understand why the sign extension was done. Copy-pasting the standard definition of the `lb` instruction isn't very helpful.. – Daniel Feb 12 '13 at 16:00
  • @Daniel, I'm not sure I understand what you're getting at. Sign extension is explicitly part of the `lb` instruction. If you didn't want sign extension, you'd use `lbu`. – Carl Norum Feb 12 '13 at 16:05
  • @CarlNorum My problem was that I didn't understand how the sign-extension was done - Michael explained to me that since the MSB of 0x88 is 1, the other 24 bits will also be 1. – Daniel Feb 12 '13 at 16:07