第一个问题是一样的。 当程序加载到内存中时,没有对数据进行特殊处理。
是的,第二个问题是编译器将执行的字节对齐。 和第一个问题一样,加载到内存时没有做特殊处理,所以文件中存储的也是对齐的。 如果说硬盘上的程序和内存上的程序有区别的话,那么最大的区别应该就是对齐粒度的问题。 硬盘上文件段的对齐粒度通常为512字节,而内存中大多数为4KB,但这与字对齐粒度不同。 部分对齐。
上面@小娜提到的C语言字节对齐的原因是不正确的。 对齐并不是为了快速寻址,而是为了减少向CPU发送内存数据的一个总线周期。 在32位环境下,一个总线周期可以传输4个字节。 假设该地址存储了一个字节的数据(比如char),后面跟着四个字节的数据(比如int),那么int就应该存储在这四个字节处,这样当CPU需要使用这个int时,它需要在第一个总线周期中读取 - ,并丢弃第一个字节,保留最后三个字节,然后在第二个总线周期中读取 - ,并丢弃最后三个字节。 字节,留下第一个字节。 这需要两个总线周期。 而如果在char后面空出3个字节直接存到-处,则只需要一个总线周期就可以将它们读出。 所以不会减少1/4或者1/8,最多可以减少1/2。 关于这一点,可以参考任何一本大学教材《微型计算机原理与接口技术》。
为了证明文件中也存在字节对齐,可以定义一个结构体,如下:
{
字符ch;
整数;
}节点;
然后声明一个全局变量(因为局部变量是在栈上分配的,无法在文件中体现) NODE node = {'a', };
经过调试运行发现逻辑地址为。 根据PE文件格式,可以计算出文件偏移量,然后使用打开的程序文件查找偏移地址,如下所示。
我选择的8个字节就是这个结构体变量。 可以看到字符'a'占据了第一个字节,但是最后三个字节填充了0x00进行字节对齐,然后int类型按照小End方式存储。