字节序,bit序以及位域

一、 字节序列大小端

如果将一个32位的整数0x87654321存放到一个整型变量(int) 中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。

地址偏移大端模式小端模式
0x008721
0x016543
0x024365
0x032187

字节的大小端主要指的是字节存放的顺序, 小端的低位在低地址,高位在高地址。我们在手动拼接网络报文的时候,需要做大小端的转化,这里的转化指的就是字节序列

#include <stdio.h>
#include <stdbool.h>

bool isBigEndian() {
  int a = 1;
  return 0 == *((char *)(&a));
}

int main(int argc, char *argv[]) {
  if (isBigEndian()) {
    printf("big endian\n");
  } else {
    printf("little endian\n");
  }
  return 0;
}

二、 bit序列

位域会按照数据结构从低到高进行存储,与计算机的大小端无关。

#include <memory.h>
#include <stdbool.h>
#include <stdio.h>

struct A {
  unsigned char a : 2;
  unsigned char b : 3;
  unsigned char c : 2;
  unsigned char d : 1;
};

int main(int argc, char *argv[]) {
  struct A a;
  // 0000 0110
  unsigned char c = 6;
  memcpy(&a, &c, sizeof(a));
  printf("a=%d, b=%d, c=%d, d=%d\n", a.a, a.b, a.c, a.d);
}

在小端机器上的输出为:

a=2, b=1, c=0, d=0

在大端机器上得输出为:

a=0, b=0, c=3, d=0

在这里插入图片描述

关于移位操作

int main(int argc, char *argv[]) {
  int i = 1;
  printf("%d\n", i << 1);
}

小端输出:

2

大端输出:

2

对于C语言的移位操作而言,左移动都表示扩大,右移动都表示缩小。

三、 使用qemu测试大小端

  1. 安装qemu支持mips
apt install qemu-user-static qemu-system-mips
  1. 安装编译mipsgcc工具
apt install gcc-mips-linux-gnu
  1. 编写程序进行测试:
#include <stdio.h>
#include <endian.h>

int main()
{
    int x = 0x1234;
    printf("0x%x, htole32 0x%x, htobe32 0x%x\n", x, htole32(x), htobe32(x));
    return 0;
}
  1. 编译,可看出编译出的程序时MSB,大端序的。需要注意的是要加上-static的编译选项否则运行时候会提示找不到链接库。
mips-linux-gnu-gcc -static xx.c
[root@ubuntu] ~
$ file a.out
a.out: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=48929411066f86d58ed7855e545b980bc92fd75b, not stripped

参考

  1. 大小端介绍
  2. qemu mips模拟大端机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值