关于ARM体系的存储系统,在后面章节会有详细的介绍。这里仅仅介绍ARM编程模型中与存储系统相关的一些概念。
ARM体系中的存储空间:
ARM体系中使用单一的地址空间。该地址空间的大小为2的32次方个8位字节。这些字节单元的地址都是无符号的32位数值,取值范围是0~2^32 - 1。
ARM的地址空间也可以看作是2^30个32位的字单元,这些字单元的地址可以被4整除,也就是说,该地址的低两位为0b00。地址为A的字数据包括地址为A+1、A+2、A+3四个字节单元的内容。
各个存储单元的地址作为32位的无符号数,可以进行常规的整数运算。这些运算的结果进行2^32取模。也就是说,运算结果发生上溢处和下溢处时,地址将会发生卷绕。
ARM存储器格式:
在ARM体系中,每个字单元中包含4个字节单元或2个半字单元;一个半字单元包含两个字单元。但是在字单元中,4个字节哪一个是高位字节,哪一个是低位字节,则有两种不同的格式:Big-endian格式和Little-endian格式。
在Big-endian格式中,对于地址为A的字单元,包括字节单元A、A+1、A+2、A+3,其中字节单元由高位到低位字节顺序为A、A+1、A+2、A+3;这种存储器格式如下表所示。
字单元A | |||
半字单元A | 半字单元A+2 | ||
31~24 | 23~16 | 15~8 | 7~0 |
字节单元A | 字节单元A+1 | 字节单元A+2 | 字节单元A+3 |
在Little-endian格式中,地址为A的字单元包括字节单元A、A+1、A+2、A+3;其中字节单元由高位到低位字节顺序为A+3、A+2、A+1、A;地址为A的字单元包括半字A、A+2,其中半字单元由高到底位字节顺序为A+2、A;这种存储格式如下表所示。
字单元A | |||
半字单元A+2 | 半字单元A | ||
31~24 | 23~16 | 15~8 | 7~0 |
字节单元A+3 | 字节单元A+2 | 字节单元A+1 | 字节单元A |
非对齐的存储访问操作:
在ARM中,通常希望字单元的地址是对齐的,半字单元的地址是半字对齐的。在存储访问操作中,如果存储单元的地址没有遵守对齐规则,则称为非对齐的存储访问操作。
指令预取和自修改代码:
在ARM中允许指令预取。在CPU执行当前指令的同时,可以从存储器中预取其后若干条指令,具体预取多少条指令,不同的ARM实现中有不同的数值。
预取的指令并不一定能够得到执行。比如当前指令执行完后,如果发生了中断异常,程序将会跳转到异常中断处理程序处执行,当前预取指令将被抛弃,或者如果执行了跳转指令,则当前预取的指令也将被抛弃。
正如在不同的ARM实现中,预取的指令条数可能不同,当发生程序跳转时,不同的ARM实现中采用的跳转预测算法也可能不同。
自修改代码指的是代码在执行过程中可能修改自身。对于支持指令预取的ARM系统,自修改代码可能带来潜在的问题。当指令被预取后,在该指令被执行前,如果有数据访问指令修改了位于主存中的该指令,这时被预取的指令和主存中对应的指令不同,从而可能是执行的结果发生错误。