简体   繁体   English

C编程:字节数组中的单词

[英]C programming: words from byte array

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. 背景是我正在为入门计算机体系结构类使用C语言编写的MIPS模拟器,但是在调试代码时遇到了令人惊讶的结果,从C编程的角度来看,我根本无法理解。

I have a byte array called mem defined as follows: 我有一个称为mem的字节数组,定义如下:

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: 在一些测试中,我将uint32_t值手动存储到四个存储块中的一个名为mipsaddr的地址处,一次一个字节,如下所示:

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 上面的代码输出如下: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. test4的值完全符合我的预期,但是foo似乎已颠倒了字节顺序。 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). 在foo的情况下,我希望uint32_t *指针指向mem [mipsaddr],由于它的长度为32位,因此它将按照它们在数组中的存在顺序读取所有32位(即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. 但是,如果没有,我希望有人能在这里启发我。

It is (among others) explained here: http://en.wikipedia.org/wiki/Endianness (在其他地方)对此进行了解释: 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. 当将大于一个字节的数据存储到内存中时,它取决于字节存储顺序的体系结构(即CPU)。 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 ;-). 在for循环中,您从最高有效字节开始按字节存储值(递减索引有点误导;-)。 Your memory looks like this afterwards: 0x00 0x00 0x10 0x84. 之后,您的内存如下所示: 0x00 0x00 0x10 0x84.

You are then reading the word back with a single 32 bit (four byte) access. 然后,您将通过单个32位(四个字节)访问来读回该单词。 Depending on our architecture, this will either become 0x00001084 (big endian) or 0x84100000 (little endian). 根据我们的体系结构,这将变为0x00001084 (大字节序)或0x84100000 (小字节序)。 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. 在第二种方法中,您使用的顺序与存储各个字节的顺序相同(最高有效位在前),因此您将获得与先前存储的相同值。

这似乎是字节顺序问题,可能是由于将(uint8_t *)转换为(uint32_t *)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM