地址对齐

ARM指令和51单片机指令不同,ARM所有指令的长度都是固定的,都是4个字节32位。而51单片机的指令的长度不是固定的,有单字节指令也有双字节指令。

ARM的数据总线宽度也是32位的,所以ARM可以处理32位的数据,这就要求所有的数据也必须是存放在地址为4的整数倍的单元处。

正常情况下,R15中的值应该为4的整数倍,访问数据时给的地址也应该是4的整数倍。这种情况就是地址对齐。如果不满足这种情况,那么就是非地址对齐。

非地址对齐访问程序存储器:

当访问程序存储器时,所给的地址是非对齐的,那么对于ARMv3及以下版本的处理器来说,会交由存储系统来忽略R15中的低两位(也就是说地址会原封不动地送到存储系统),然后进行取址。对于ARMv4及以上版本的处理器,如果出现非对齐访问,那么会出现不可预知的结果。

对于Thumb指令,如果出现非地址对齐访问程序存储器,那么最低位将会由存储器系统来忽略,然后进行取址。

非地址对齐访问数据:

不同的指令会出现不同的处理情况。

1、出现不可预知的错误。

2、交由存储系统来忽略地址的低两位,也就是说地址原封不动地送到存储系统中。

3、由处理器内核忽略地址的低两位。

时间: 2024-10-10 00:22:51

地址对齐的相关文章

[C/C++]_[中级]_[数据地址对齐]

场景: 1. 有些频繁使用的指针变量地址不对齐的话运行效率和对齐后的运行效率差别很大,所以在创建堆空间时,有必要对内存地址对齐提高运行效率. 2. 有些音视频处理的代码或者说自定义的malloc基本都是地址对齐的. 3. 使用原子访问的互锁函数时,InterlockedExchangeAdd都需要地址对齐. 4. 主要还是宏APR_ALIGN, 这个说是Apache源码里,就借用一下吧. 解决方案: 1. 其实就是让地址值对对齐量求模为0, 地址值最多增加n-1个偏移地址就可就可以整出n.  &

C语言精要总结-内存地址对齐与struct大小判断篇

在笔试时,经常会遇到结构体大小的问题,实际就是在考内存地址对齐.在实际开发中,如果一个结构体会在内存中高频地分配创建,那么掌握内存地址对齐规则,通过简单地自定义对齐方式,或者调整结构体成员的顺序,可以有效地减少内存使用.另外,一些不用边界对齐.可以在任何地址(包括奇数地址)引用任何数据类型的的机器,不在本文讨论范围之内. 什么是地址对齐 计算机读取或者写入存储器地址时,一般以字(因系统而异,32位系统为4个字节)大小(N)的块来执行操作.数据对齐就是将数据存储区的首地址对齐字大小(N)的某个整数

Avalon总线的地址对齐与NIOS编程

首先关于地址对齐的概念我不详述了,大家可以参考这篇文章:Avalon总线的地址对齐:Dynamic Addressing和Native Addressing. 假设我们定制了一个外设,数据宽度是32位,地址是2位.如果我们想让地址线干点其他的事,而不是传地址,例如: 1 if(cs&wr) 2 begin 3 case(addr) 4 2'b00: //自定义 5 2'b01: //自定义 6 endcase 7 end 那在Nios EDS中,如何确定addr呢?也就是说我们使用IOWR_32

【信息表示】地址对齐

本节研究地址对齐的相关问题: 地址对齐 说明几点: (1)地址对齐可以简化处理器和存储器系统之间的硬件设计:如果可以保证所有的int类型地址对齐成4的倍数,就可以使用一个存储器操作读或写值,相反如果一个int型的变量存放在奇地址上,那么要进行两次存储器读后进行拼凑成int型变量才可以: (2)在GCC中,2字节数据类型(如short)地址对齐必须是2的倍数,因此地址最低位必须是0,而较大的数据类型(如int.int*.float.包括long long.double.long double)的地

Avalon总线的地址对齐与EDS编程

首先关于地址对齐的概念我不详述了,大家可以参考这篇文章:Avalon总线的地址对齐:Dynamic Addressing和Native Addressing. 假设我们定制了一个外设,数据宽度是32位,地址是2位.如果我们想让地址线干点其他的事,而不是传地址,例如: 1 if(cs&wr) 2 begin 3 case(addr) 4 2'b00: //自定义 5 2'b01: //自定义 6 endcase 7 end 那在Nios EDS中,如何确定addr呢?也就是说我们使用IOWR_32

C语言结构体变量内存分配与地址对齐

地址对齐简单来说就是为了提高访问内存的速度. 数组的地址分配比较简单,由于数据类型相同,地址对齐是一件自然而然的事情. 结构体由于存在不同基本数据类型的组合,所以地址对齐存在不同情况,但总体来说有以下规则: 原则1:数据成员对齐规则:结构的数据成员,第一个数据成员放在偏移量(offset)为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 原则2:收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大

#pragma pack 定义变量的起始存放地址对齐方式

pack用来指定变量在内存中的存放起始地址对齐方式: 具体用法如下: 1 #pragma pack(push,n) // 保存当前系统设置的对齐方式,压入堆栈,然后设置当前对齐方式为n字节对齐,n通常取 1 2 4 8 2 3 ......... 4 5 #pragma pack(pop) // 恢复当前的对齐方式 pack对齐方式:选当前数据类型本身占用字节数与pack指定的对齐字节数两者之间的最小值, 用这个最小值的整数倍作为存放的起始地址. 例1: 1 #pragma pack(push,

【转】内存地址对齐运算

做地址对齐的代码: #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) //为了满足需要内存对齐的系统 这段代码做的事情就是,给定一个变量n,算出这个变量对齐到某个字长(整型的字节数)整数倍的字节数.这段代码有些难以理解.那么慢慢分析下吧. 假设有一个地址n,要把n按m对齐,无非就是找到大于等于n且整除m的最小的那个数. 我们定义一个宏函数F,它计算n按m对齐的结果,则按照上段代码的逻辑,F定义为: #def

【转】一个跟地址对齐有关的应用异常案例

@2019-01-29 [小记] 一个跟地址对齐有关的应用异常案例 原文地址:https://www.cnblogs.com/skullboyer/p/10335373.html