1

I have some confusion regarding reading a word from a byte array. The background context is that I'm working on a MIPS simulator written in C for an intro computer architecture class, but while debugging my code I ran into a surprising result that I simply don't understand from a C programming standpoint.

I have a byte array called mem defined as follows:

uint8_t *mem;
//...
mem = calloc(MEM_SIZE, sizeof(uint8_t)); // MEM_SIZE is pre defined as 1024x1024

During some of my testing I manually stored a uint32_t value into four of the blocks of memory at an address called mipsaddr, one byte at a time, as follows:

for(int i = 3; i >=0; i--) {
         *(mem+mipsaddr+i) = value;
         value = value >> 8;
         // in my test, value = 0x1084
}

Finally, I tested trying to read a word from the array in one of two ways. In the first way, I basically tried to read the entire word into a variable at once:

uint32_t foo = *(uint32_t*)(mem+mipsaddr);
printf("foo = 0x%08x\n", foo);

In the second way, I read each byte from each cell manually, and then added them together with bit shifts:

    uint8_t test0 = mem[mipsaddr];
    uint8_t test1 = mem[mipsaddr+1];
    uint8_t test2 = mem[mipsaddr+2];
    uint8_t test3 = mem[mipsaddr+3];

    uint32_t test4 = (mem[mipsaddr]<<24) + (mem[mipsaddr+1]<<16) + 
               (mem[mipsaddr+2]<<8) + mem[mipsaddr+3];
    printf("test4= 0x%08x\n", test4);  

The output of the code above came out as this: foo= 0x84100000 test4= 0x00001084

The value of test4 is exactly as I expect it to be, but foo seems to have reversed the order of the bytes. Why would this be the case? In the case of foo, I expected the uint32_t* pointer to point to mem[mipsaddr], and since it's 32-bits long, it would just read in all 32 bits in the order they exist in the array (which would be 00001084). Clearly, my understanding isn't correct.

I'm new here, and I did search for the answer to this question but couldn't find it. If it's already been posted, I apologize! But if not, I hope someone can enlighten me here.

4
  • Just to be clear, mipsaddr is defined within [1, MEM_SIZE), although I didn't give it here. Commented Oct 5, 2012 at 5:59
  • It seems to be a problem of endianness Commented Oct 5, 2012 at 6:01
  • In first code, try writing value = value >> 8 * i; Let me know if this helps. Commented Oct 5, 2012 at 6:02
  • always good to mention what compiler/platform you are on with problems of this category. Commented Oct 5, 2012 at 6:08

2 Answers 2

4

It is (among others) explained here: http://en.wikipedia.org/wiki/Endianness

When storing data larger than one byte into memory, it depends on the architecture (means, the CPU) in which order the bytes are stored. Either, the most significant byte is stored first and the least significant byte last, or vice versa. When you read back the individual bytes through byte access operations, and then merge them to form the original value again, you need to consider the endianess of your particular system.

In your for-loop, you are storing your value byte-wise, starting with the most significant byte (counting down the index is a bit misleading ;-). Your memory looks like this afterwards: 0x00 0x00 0x10 0x84.

You are then reading the word back with a single 32 bit (four byte) access. Depending on our architecture, this will either become 0x00001084 (big endian) or 0x84100000 (little endian). Since you get the latter, you are working on a little endian system.

In your second approach, you are using the same order in which you stored the individual bytes (most significant first), so you get back the same value which you stored earlier.

Sign up to request clarification or add additional context in comments.

Comments

0

It seems to be a problem of endianness, maybe comes from casting (uint8_t *) to (uint32_t *)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.