原创 MIPS 下非对齐访问的问题

2010-3-14 19:19 3637 15 16 分类: MCU/ 嵌入式

 


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 为例,其他类似):


ab40486e-c786-44b2-b390-db7e7eb0a2ee.jpg



上图解释的是小端模式下的情况,大端模式的情况则相反:首先 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 只能访问内存的始地址到下一个对齐地址处。
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2015-9-15 15:12

讲的很好。
相关推荐阅读
bellstudio_534338181 2010-09-12 18:12
亚克力是个啥?
/************摘自百度百科************/压克力简介基本信息  亚克力由英文Acrylics音译而来。亚克力的的化学名叫聚甲基丙烯酸甲酯 (Polymethylmethacryl...
bellstudio_534338181 2010-05-20 23:06
Q格式
以下内容转自百度百科 Q格式目录[隐藏]Q格式前提 DSPs DSP芯片的定点运算 1. 数据的溢出: 2. 定点处理器对浮点数的处理: 3. Q格式的运算 4. Q格式的应用格式Q格式前提 DSPs...
bellstudio_534338181 2010-05-08 13:21
再说PID调节
以前转过一篇PID调节的文章,不过没有这个详细。今天再学习一下。====================没有一种控制算法比PID调节规律更有效、更方便的了。现在一些时髦点的调节器基本源自PID。甚至可...
bellstudio_534338181 2010-04-30 10:42
晕死,派睿居然收购了EAGLE
都是去年的事情了,不过一直不知道,今天去那边看才发现这么一则公告。十分诧异,一个目录分销商,买这么一个做CAD软件的公司,真是令人不解。Premier Farnell Acquires CadSoft...
bellstudio_534338181 2010-04-30 09:27
血氧仪原理简述
血红蛋白是血细胞的重要组成部分,它负责将氧气从肺部输送到身体的其它组织。血红蛋白在任一时刻所含的氧气量被称为血氧饱和度(即SpO2)。血氧饱和度是反映人体呼吸功能及氧含量是否正常的重要生理参数,它是显...
bellstudio_534338181 2010-04-26 00:14
Microchip公布停止MPLAB ICD2更新支持的时间表
MPLAB ICD2是Microchip提供的全平台调试/烧写工具,现在其网站上已经公布了停止对ICD2支持的时间表。自2010年9月之后,ICD2将不能支持新推出的MCU和dsPIC系列产品。新的调...
EE直播间
更多
我要评论
1
15
关闭 站长推荐上一条 /3 下一条