织梦CMS - 轻松建站从此开始!

罗索

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

jackyhwei 发布于 2010-04-10 00:38 点击:次 
寄存器分配: 1. 遵循ATPCS调用规则的函数,必须保护被调用寄存器r4~r11的值。同时规定堆栈应是8字节边界对齐的,以下是寄存器压栈和出栈的模板: routine_name STMFD sp!, {r4-r12, lr} ;r12的使用是不需要压栈保存的,这里压栈仅仅是为了保证8字节边界对齐!
TAG:


寄存器分配:

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; STMDA --- LDMIB; STMDB --- 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

 

(秩名)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201004/9064.html]
本文出处:CSDN博客 作者:秩名
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容