【无标题】
2024-01-09 21:39:54
1. 关于大小端存储的概念
首先需要一些概念:
对于一个 ω \omega ω位的整数,其位表示为[x ω \omega ω-1, x ω \omega ω-2, …, x2, x1]。其中:
- 最高有效字节: [x ω \omega ω-1, x ω \omega ω-2, …, x ω \omega ω-7, x ω \omega ω-8];
- 最低有效字节: [x7, x6, …, x1, x0];
- 大端法(big endian):最高有效字节位于内存的低地址;最低有效字节位于内存的高地址;
为方便记忆,可以将大端法类比为日常手写数字的顺序,左侧(内存中的低地址)是数字高位有效数字,右侧是低位数字。
- 小端法(little endian):与大端法相反
以32位int整数0x12345678
为例,该int位于内存的地址位0x100
,则两种情况的内存分布为:
2. 关于大小端存储的应用
- 不同存储的设备通过网络收发二进制数据,如果收发的设备不同,发送的顺序会与接受顺序相反。具体看CSAPP第12章(暂未看到)
- 关于小端存储机器级指令的阅读:
已知上述代码设计两个数相加:PC寄存器中的值和4004d3: 01 05 43 0b 20 00 add %eax,0x200b43(%rip)
0x200b43
。0x200b43这个值位于指令的最后四个字节:43 0b 20 00, 根据小端存储的定义并去掉第一个符号位字节,该数值即为20 0b 43
3.通过C代码测试本机器是小端存储还是大端存储
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len) {
size_t i;
for (i = 0; i < len; ++i) {
printf(" %.2x", start[i]);
}
printf("\n");
}
// 使用sizeof并用size_t类型接受,从而不受编译环境的影响·
void show_int(int x) {
show_bytes((byte_pointer)&x, sizeof(int));
}
void show_float(float x) {
show_bytes((byte_pointer)&x, sizeof(float));
}
void show_void(void *x) {
show_bytes((byte_pointer)&x, sizeof(void *));
}
void test_show_bytes(int val) {
int ival = val;
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_void(pval);
}
int main()
{
test_show_bytes(12345);
return 0;
}
以下是在Linux 32bit和Linux 64bit测试结果:
## linux 32
39 30 00 00
00 e4 40 46
04 79 84 bf
## linux 64
39 30 00 00
00 e4 40 46
a8 72 70 39 fd 7f 00 00
十进制12345的十六进制表示位0x00003039
, 上述机器均为小端存储。
还有其他的巧妙测试方法:
- 强制转换:
#include <iostream> using namespace std; int main() { int a = 0x1234; //由于int和char的长度不同,借助int型转换成char型,只会留下低地址的部分 char c = (char)(a); if (c == 0x12) cout << "big endian" << endl; else if(c == 0x34) cout << "little endian" << endl; }
- 使用联合体
#include <iostream> using namespace std; //union联合体的重叠式存储,endian联合体占用内存的空间为每个成员字节长度的最大值 union endian { int a; char ch; }; int main() { endian value; value.a = 0x1234; //a和ch共用4字节的内存空间 if (value.ch == 0x12) cout << "big endian"<<endl; else if (value.ch == 0x34) cout << "little endian"<<endl; }
上述两种方法参考来源:阿秀的校招笔记
文章来源:https://blog.csdn.net/weixin_43869409/article/details/135488494
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!