内存地址对齐及大小端
来源:互联网 发布:淘宝卖手办的店 编辑:程序博客网 时间:2024/06/05 11:08
考虑这样一个例子: 两个异构的CPU进行通信,定义了这样一个结果来传递消息:
struct Message
{
short opcode;
char subfield;
long message_length;
char version;
short destination_processor;
}message;
用这样一个结构来传递消息貌似非常方便, 但也引发了这样一个问题: 若这两种不同的CPU对该结构的定义不一样,两者就会对消息有不同的理解. 有可能导致二义性. 会引发二义性的有这两个方面:
- 内存地址对齐
- 大小端定义
本文先介绍内存地址对齐和大小端的概念,再回头来看这个例子就豁然开朗了.
内存地址对齐
?/P>
洋名叫做" ByteAlignment".
大部分16位和32位的CPU不允许将字或者长字存储到内存中的任意地址.比如Motorola 68000不允许将16位的字存储到奇数地址中,将一个16位的字写到奇数地址将引发异常.
实际上, 对于c中的字节组织, 有这样的对齐规则:- 单个字节(char)能对齐到任意地址
- 2字节(short)以2字节边界对齐
- 4字节(int, long)以4字节边界对齐
为什么会有上述的限制呢? 理解了内存组织, 就会清楚了
CPU通过地址总线来存取内存中的数据,32位的CPU的地址总线宽度既为32位置, 标为A[0:31]. 在一个总线周期内,CPU从内存读/写32位. 但是CPU只能在能够被4整除的地址进行内存访问,这是因为: 32位CPU不使用地址总线的A1和A2. (比如ARM,它的A[0:1]用于字节选择, 用于逻辑控制, 而不和存储器相连,存储器连接到A[2:31].)
访问内存的最小单位是字节(byte), A0和A1不使用, 那么对于地址来说,最低两位是无效的, 所以它只能识别能被4整除的地址了. 在4字节中,通过A0和A1确定某一个字节.
再看看刚才的message结构, 你想想它占了多少字节?别想当然的以为是10个字节. 实际上它占了12个字节. 不信?用sizeof(message)看吧. 对于结构体,编译器会针对起中的元素添加"pad"以满足字节对齐规则.message会被编译器改为下面的形式:
struct Message
如果不同的编译器采用不同的对齐规则, 对传递message可就麻烦了.{
short opcode;
char subfield;
char pad1; // Pad to start the long word at a 4 byte boundary
long message_length;
char version;
char pad2; // Pad to start a short at a 2 byte boundary
short destination_processor;
char pad3[4]; // Pad to align the complete structure to a 16 byte boundary
};
Byte Endian
是指字节在内存中的组织,所以也称它为ByteOrdering.
(1) 它的地址是多少?
(2) 它的字节在内存中是如何组织的?
比如: int x, 它的地址为0x100.那么它占据了内存中的Ox100, 0x101, 0x102,0x103这四个字节.
[Xw-1, Xw-2, ... , X1,X0]
两个测试BitEndian的小程序
method_1
#include <stdio.h>
int main(int argc, char *argv[])
{
}
method_2
#include <stdio.h>int main(void)
{
/* Each component to a union type is allocated storage at thebeginning of the union */
}
- 内存地址对齐及大小端
- 内存地址对齐及大小端
- 内存地址对齐及大小端
- 内存地址对齐及大小端
- 内存地址对齐及大小端
- 内存地址对齐及大小端
- C-内存地址对齐及大小端
- 内存地址对齐及大小端
- 内存地址对齐及大小端
- [转载]C-内存地址对齐及大小端
- c/c++内存地址对齐及大小端
- 内存地址对齐及大小端 (转)
- 内存对齐及大小端
- 内存对齐及大小端
- 内存-大小端对齐
- 大小端及内存对齐问题细议
- C++ 内存对齐及空类大小
- C语言之struct大小、首地址与内存对齐
- objdump代码分析
- Oracle---DBMS_SQL----动态SQL语句
- 我还是一个人.....
- 将指定的表/视图中的数据导出为 html 文件
- 同济大学软件学院万院长谈择业
- 内存地址对齐及大小端
- 非常显然:各正整数不可与各非0整数一 一对应
- c/c++ 资源
- JAVA去掉一个已排序数组的重复数字
- 微软把用户变成了傻瓜,却指责傻瓜不聪明
- 老紫竹JAVA提高教程(1)-认识Set集合
- 老紫竹JAVA提高教程的说明
- JOJO替身分析
- 系统程序员成长计划-Write once, run anywhere(WORA)(上)