1.问题

  MIPS 下使用访存指令读取或写入数据单元时,目标地址必须是所访问之数据单元字节数的整数倍,这个叫做地址对齐。

比如在 MIPS 平台上,lh 读取一个半字时,存储器的地址必须是 2 的整数倍; lw 读取一个字时,存储器的地址必须是 4的整数倍; sd 写入一个双字时,存储器的地址必须是 8 的整数倍。倘若访存时,目标地址不对齐,则会引起异常,典型的是系统提示“总线错误”后,直接杀死进程。

看一个测试程序(龙芯2E平台):

#include <stdio.h>
#include <sys/sysmips.h>

unsigned short data[] = {
  0x1, 0x2, 0x3, 0x4,
  0x55aa, 0x66bb, 0x77cc, 0x0000,
};

inline void unaligned_access(unsigned short * const row)
{
  asm volatile
    (
        ".set mips3\n\t"
        ".set noreorder\n\t"

//"lwr $10, 1(%1)\n\t"
        //"lwl $11, 4(%1)\n\t"
        //"or $10, $11\n\t"
        "ld $10, 2(%1)\n\t"     /* %1 is double word aligned, %1+2 is double word unaligned */
        "sd $10, %0\n\t"

".set reorder\n\t"
        ".set mips0\n\t"
        : "=m"(*(row))
        : "r"(row+4)
        : "$8", "$9", "$10"
    );
}

int main()
{
  printf("---------------------------------------------------------\n");
  printf(" Testing Godson2 unaligned access Instruction \n");
  printf("---------------------------------------------------------\n\n");

// sysmips(MIPS_FIXADE, 0);

unaligned_access(data);

printf("result is: 0x%04x %04x %04x %04x\n", data[3], data[2], data[1], data[0]);

}

程序运行后系统提示“非法指令”后退出。

CISC 下(如x86)访存时,如果目标地址不对齐,CPU 不会陷入异常,因为其内部有处理非对齐访问的微程序。

2. 解决

  高级语言中一般不会遇到这种问题,编译器常常会处理好数据类型的对齐。但万一遇到、抑或在汇编里遇到,避不开怎么办?

可以使用 MIPS 的指令集里提供的 lwr/lwl, swr/srl, ldr/ldl, sdr/sdl 指令对。关于他们的原理可以用下图来简单的示意一下(以ldr/ldl 为例,其他类似):

  上图解释的是小端模式下的情况,大端模式的情况则相反:首先 ldl t0, 0(t1),然后再 ldr t0, 7(t1)。

  可以看到无论大端模式还是小端模式,非对齐访问的解决都是将原来的一条指令(对齐访问)完成的事分两步完成,即首先取始地址 addr 到下一个对齐地址处的部分数据,置入寄存器右部(小端),(大端置入左部(高位)),然后取从该对齐地址到 addr + len - 1 处的部分数据(len 为数据单元长度,半字为2, 双字为8),置入寄存器左部(小端)。

如小端机器上,始地址为 t1 = 0x1022,则:

ldr t0, 0(t1) 取 0x1022~0x1027 到 t0 的右部
ldl   t0, 7(t1) 取 0x1028~0x1029 到 t0 的左部

  注意上述指令的后缀 r(right), l(left) 都是相对寄存器而言,load 操作是把取到的部分数据,置入寄存器的 left 或者 right, store 操作是将寄存器中数据的 left 或者 right 部分,写入目标地址而已。无论大端和小端寄存器的格式都是固定的,即右端为低位,左端为高位。任意第一条ldr/ldl/lwr/lwl/sdr/sdl/swr/swl 只能访问内存的始地址到下一个对齐地址处。

转载于:https://www.cnblogs.com/sevenir-code/p/4888490.html

[转]MIPS 下非对齐访问的问题相关推荐

  1. ARM非对齐访问和Alignment Fault

    转载自ARM非对齐访问和Alignment Fault - 者旨於陽 - 博客园 (cnblogs.com) 1.指令对齐 A64指令必须word对齐.尝试在非对齐地址取值会触发PC alignmen ...

  2. 结构体成员非对齐访问所带来的思考

    [摘要]本文介绍了内存访问时为什么需要对齐及不对齐时带来的影响.接着介绍了如何改变对齐规则来保证CPU能够访问非对齐内存.最后介绍了结构体设计时需要注意的问题,如何调整成员顺序或者填充特定单元来避免平 ...

  3. Axi:名词解释、乱序、间插、卷绕、窄带访问、非对齐访问、OST

    信号说明: AWBURST.ARBURST: 指示burst type,有3种burst类型. Fixed:固定地址模式,每次burst传输首地址固定,用于访问FIFO INC:递增递增模式,每次传输 ...

  4. stm32h743外部RAM非字节对齐访问,引起的hard fault

    我遇到的情况非常相似,我先说说我遇到的情况:由于公司的STM32F437买不来了,价格500+, 但是STM32H743却只有200+,于是我收到了一个任务,用STM32H743替换之前的F437: ...

  5. ARMv8-A非对齐数据访问支持(Alignment support)

    目录 1,对齐传输和非对齐传输 2,AArch32 Alignment support 2.1 Instruction alignment 指令对齐 2.2 Unaligned data access ...

  6. 单片机(MCU)如何才能不死机之对齐访问(Aligned Access)

    从一个结构体说起.如下,在 STM32F0 的程序中,我们定义了一个结构体My_Struct ,那么这个结构体占用多少内存呢? struct Struct_Def { uint8_t Var_B; u ...

  7. CM3中数据传输对齐/非对齐方式

    在CM3中,非对齐的数据传输只发生在常规的数据传送指令中,如LDR.LDRH.LDRSH.其他指令则不支持,包括: 1.多个数据的加载.存储(LDM/STM). 2.堆栈操作PUSH.POP. 3.互 ...

  8. ARM 指令 对齐访问等

    关于 ARMv8 的基础知识,请查看这篇文章 ARMv8 简介. ARM 指令 指令编码 逻辑运算指令 LSL 逻辑左移 按操作数所指定的数量向左移位,低位用零来填充 ASL 算术左移 同逻辑左移,A ...

  9. rtthread 字节对齐问题 int指针访问非对齐地址崩溃

    rtthread 字节对齐问题 int指针访问非对齐地址崩溃 环境: SOC: i.MX RT1050 底板: 野火 RT1052 Kernel: rt-thread 背景: 我正在实现解析udp包, ...

最新文章

  1. xxl-job Vs ElasticJob,谁牛?
  2. Beta阶段——第4篇 Scrum 冲刺博客
  3. LeetCode——Find the Difference
  4. Java中集合中根据对象的某个属性去重
  5. Element Select多选选中项溢出选项框
  6. 惠普打印机136w硒鼓芯片怎么清零_关于惠普彩激升级后无法识别硒鼓的处理方案...
  7. docker jenkins
  8. camera(21)---MTK android AF调试总结
  9. python的__name__
  10. SAP License:SAP学习之COPP
  11. js swipe 图片滑动控件实现 任意尺寸适用任意屏幕
  12. python安装包下载
  13. 国内外优秀的设计素材网站推荐
  14. 化工过程机械类毕业论文文献有哪些?
  15. mysql数据库击穿_缓存穿透、击穿、雪崩区别和解决方案
  16. spring boot 整合 jpa
  17. js如何修改对象的padding属性
  18. 【React Native】使用react-native-wechat 进行微信好友、微信朋友圈进行分享
  19. dram sram drom srom ddram详细解释
  20. (Note)七彩虹30系列显卡——《一键超频》按键

热门文章

  1. 【转】一个40岁老程序员的前端学习之路|2021 年中总结
  2. 高斯主元素消去法c语言,列主元Gauss消去法(C++实现)
  3. php 变量字节大小,PHP 变量
  4. python中intvar_Python的IntVar设置
  5. python正则替换查询_使用Python中的正则表达式进行搜索和替换
  6. linux 扩展swap虚拟内存
  7. 接口规范 6. 查看在线用户
  8. java 注解学习_JAVA注解学习
  9. 目标识别:如何从人脸图片中扣出眼图,实时人脸人眼检测和识别
  10. Java查找一个字符串中所有匹配某正则的子串