高低字节与数组

高低地址和高低字节都是对于大于8位数据而言,读取的数据是整个数据读取,即使是一个结构体(struct)或者联合体(union)。

比如一个uint16_t num = 0x1234的数据就需要定义一个uint8_t buffer[2], 其中:

高8位DATAH是0x12,

低8位DATAL是0x34,

 

通常数组开始从低字节开始,对应起来就是DATAL=buffer[0], DATAH=buffer[1]。(注:这里数组与联合体数组成员解析内存数据要避免混淆)

正常来说DATAL和DATAH地址是连续的,就可以将buffer直接存入到对应寄存器中。

 

对于计算机而言,计算机电路基本是不管高低字节的,都是按内存顺序处理,效率比较高(就像数组一样,都是从第0个字节开始算)。

如果计算机系统优先从高位往低位读取数据存放到内存中,那么这个排列顺序就是大端;DATAH在数组前面buffer[0],DATAL在数组后面buffer[1]

如果计算机系统优先从低位往高位读取数据存放到内存中,那么这个排列顺序就是小端;DATAL在数组前面buffer[0],DATAH在数组后面buffer[1]

 

地址与字节联系在一起还有大小端机器的存储方式。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <stdint.h>

typedef union {
    uint16_t dat;
    uint8_t buf[sizeof(uint16_t)];
} MEM_DAT;

int isBigEndian(void)
{
    int result = 0;
    uint64_t iSize = sizeof(uint16_t);

    if (iSize == 2) {
        MEM_DAT endian = {0};        /* Always store from the low address. */
        endian.dat     = 0x0001;     /* low byte;0x01, high byte:0x00 */
        
        #if 0 
        uint8_t buffer[sizeof(uint16_t)] = {0};
        memcpy(buffer, &endian.dat, sizeof(uint16_t));

        /* buffer[0] = 0x01;  // always low byte */
        printf("buffer:[%x], [%x]\n", buffer[0], buffer[1]);
        #endif
        
        if (endian.buf[0] == 0x01 && endian.buf[1] == 0x00) {
            /* Low addr -> Low byte */
            printf("little endian.\n");
            result = 0;
        } else if (endian.buf[0] == 0x00 && endian.buf[1] == 0x01) {
            /* Low addr -> High byte */
            printf("big endian.\n");
            result = 1;
        } else {
            printf("unkown data.\n");
            result = -1;
        }

    } else {
        printf("unkown size(%lu).\n", iSize);
        result = -1;
    }

    return result;
}

int main(int argc, char *argv[])
{

    uint32_t iNum = 0x12345678; // 0x1........8: byte High -> Low
    uint8_t buffer[4] = {0};    // b[0] -> b[3]: byte Low -> High

    memcpy(buffer, &iNum, sizeof(buffer));
    // buffer[0] = 0x78; 0111 1000 Bit 7:0
    // buffer[1] = 0x56; 0101 0110 Bit 15:8
    // buffer[2] = 0x34; 0011 0100 Bit 23:16
    // buffer[3] = 0x12; 0001 0010 Bit 31:24
    printf("buffer:[%x],[%x],[%x],[%x]\n", buffer[0], buffer[1], buffer[2], buffer[3]);
    isBigEndian();

    return (EXIT_SUCCESS);
}

 

posted @ 2020-05-27 09:43  sciapex  阅读(1475)  评论(0编辑  收藏  举报