分享

基于ARM的汇编优化和基本指令用法 - ARM开源共享 - 61IC代码工厂 - 开阔思路,放飞想象,步入顶尖电子开发工程师的成长通道!

 techres 2011-03-15

基于ARM的汇编优化和基本指令用法

【整理者】61ic.com
【提供者】rtweww
【详细说明】基于ARM的汇编优化和基本指令用法

寄存器分配:

1. 遵循ATPCS调用规则的函数,必须保护被调用寄存器r4~r11的值。同时规定堆栈应是8字节边界对齐的,以下是寄存器压栈和出栈的模板:

routine_name

    STMFD   sp!, {r4-r12, lr}   ;r12的使用是不需要压栈保存的,这里压栈仅仅是为了保证8字节边界对齐!
    ;body of routine
    ;the fourteen registers r0 - r12 and lr are available
    LDMFD   sp!, {r4-r12, pc}   ;符合 ! 表示sp值随入/出栈(数据传送)而改变,即sp是数据出/入栈的起始或基地址


多寄存器传送指令:

1. 多寄存器传送load-store指令寻址模式读取处理大块连续数据:IA / IB / DA / DB : (基地址)执行后/前 增加/减少

2. 更新基地址的load-store指令对:用于临时保存一组寄存器,使用完毕后再恢复它们的场合
   STMIA --- LDMDB; STMIB --- LDMDA; SA --- LDMIB; SB --- LDMIA
   如:STMIB r0!, {r1-r3} ... LDMDA r0!, {r1-r3} --- 不但恢复r1~r3, r0的地址也恢复了。

3. 堆栈操作寻址方式---在ATPCS标准,堆栈被定义为递减满堆栈,因此LDMFD和STMFD指令分别用来支持pop和push功能。
   

处理器模式寄存器cpsr的条件标志(MSB 5-bit):

1. 由比较指令或带有后缀S的ALU操作结果来设置,比如,如果一条SUBS减法指令产生了一个结果为0的寄存器值,则cspr中的Z标志位被置位(通过判断这个位可以做随后的相应操作)。

2. 大多数指令都有一个条件属性,再根据条件标志位的情况,决定内核是否执行该指令。执行前,处理器比较该条件属性和cpsr的条件标志位,匹配则执行,否则 被忽略。条件属性作为指令助记符的后缀被编码进指令,如EQ,NE,MI,PL,HI,LS,GE,LT,GT,LE,AL...(24)。


常用指令操作方式:

1. 移位指令:
   MOV r7, r5    ;r5可以是立即数,寄存器,或桶型移位器处理过的结果
   MOV r7, r5, LSL #2    ;(LSL, LSR, ASR, ROR, RRX)
   MOVS r0, r1, LSL #1    ;因为指令助记符中有S出现,故cpsr的C标志位会被更新

2. 算术指令:
   SUB r0, r1, r2
   RSB r0, r1, #0    ;r0 = 0-r1 逆向减法,用于对某数取反
   SUBS r1, r1, #1    ;带助记符的减,很方便的实现循环计数器的递减操作,cpsr的Z和C位被影响
   ADD r0, r1, r1, LSL #1    ;r1<<1 + r1, 及r0 = r1*3

3. 逻辑指令:
   ORR r0, r1, r2
   BIC r0, r1, r2    ;<==>r0 = r1 AND NOT(r2), 常用于改变cpsr中的中断屏蔽位

4. 比较指令:
   把一个寄存器与一个32位值做比较,比较结果更新cpsr的标志位,但不影响参与比较的其他寄存器。设置标志位后,其他指令可通过条件执行来改变程序的执行流程。对于比较指令,不需要使用S后缀就可以改变标志位。
   r0 = 4 r9 = 4    CMP r0, r9   ;POST cpsr=nZcvqiFt_USER
   本质上是一个不返回运算结果的减法指令,类似,TST是一个没有保存结果的逻辑"与"操作,TEQ是一个逻辑"异或"操作,每个操作部需要保存运算结果,只根据结果影响cpsr位。

5. 乘法指令:
   MUL r0, r1, r2   ;32位乘
   MLA r0, r1, r2   ;32位乘累加,r0 = r0 + r1*r2
   SMLAL             ;长整形有符合乘累加   
   SMULL             ;长整形有符合乘
   UMLAL             ;长整形无符合乘累加
   UMULL r0, r1, r2, r3    ;长整形无符合乘   [r1, r0] = r2*r3

6. 分支指令: (B, BL, BX, BLX)
   B   跳转              pc=lable
   BL 带返回的跳转      pc=lable lr=BL后面的第一条指令地址
       BL     subroutine
       CMP    r1, #5
       MOVEQ r1, #0
       ...

   subroutine
       <子程序代码>
       MOV    pc, lr   ;返回

7. load-store指令类型一:单寄存器传送指令
   LDR   r0, [r1, #4]   ;前变址,r1不变
   LDRB r0, [r1], #4   ;后变址,r1=r1+4
   LDRH r0, [r1, #4]! ;回写型前变址,r0=[r1+4], r1=r1+4

8. load-store指令类型二:多寄存器传送指令 (IA, IB, DA, DB)
   LDMIA = r0!, {r1-r3}   ; 见上面多寄存器传送指令

9. load-store指令类型三:交换指令
   SWP r0, r1, [r2]    ;字交换,内存r2地址处值读到r0寄存器,r1寄存器值存入r2所指地址处。可以字节交换SWPB

10. 常量的装载:
   ARM增加2条伪指令,用于把一个32位的常量送入寄存器
   LDR   Rd,   constant   ;常量装载伪指令<==>编译器转化为 MOV r0, #constant
   ADR   Rd,   lable      ;地址装载伪指令
   MVN   Rd,   #constant ;实际多使用这个,效率高些

11. 条件执行:
   指令只有当条件代码标志与给定的条件匹配时才执行,主要依赖两部分:条件码和条件标志,前者在指令中,后者在cpsr中。分析下例:
   while(a!=b)
   {
       if(a>b) a -= b; else b -= a;
   }
   //++仅使用可条件执行的分支指令:
   gcd
         CMP   r1, r2
         BEQ   complete
         BLT   lessthan
         SUB   r1, r1, r2
         B     gcd
   lessthan
         SUB   r2, r2, r1
         B     gcd
   complete
   ...

   //++全部使用条件执行:
   gcd
         CMP    r1, r2
         SUBGT r1, r1, r2
         SUBLT r2, r2, r1
         BNE    gcd

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多