ARM体系结构与编程学习(六)

来源:互联网 发布:淘宝企业店铺公司简介 编辑:程序博客网 时间:2024/05/22 03:09

ADR伪指令实例

;设置本段程序的名称及属性

AREA   adrlabel ,CODE,READONLY

             ENTRY

start

;跳转到子程序func执行

             BL  func

;调用angel_SWIreason_ReportException

;ADP_Stopped_ApplicationExit

;ARM semihosting SWI

stop

            MOV  R0,#0X18                  ;将0X18赋值给R0,0x18立即数对应宏angel_SWIreason_ReportException

            LDR   R1,=0X20026           ;将0X20026 赋值给R1,0X20026 立即数对应宏ADP_Stopped_ApplicationExit,表示程序

                                                      ;正常退出

            SWI   0X123456                 ;结束程序,将控制权交给调试器

;定义一个数据缓冲区,用于生成地址标号相对于PC的偏移量

            LTORG

func

;下面的伪指令ADR被汇编成:SUB  R0,PC ,#OFFSET TO START

            ADR  R0,start

;下面的伪指令ADR被汇编成:ADD  R1,PC,#OFFSET TO DataArea

            ADR  R1,DataArea

;下面的伪指令ADR汇编时错误,因为第二个操作数不能用DataArea+4300表示

;         ADR  R2,DataArea+4300

;下面的伪指令ADRL被汇编成两条指令:

;          ADD  R2 ,PC,#OFFSET1

;            ADD  R2,R2,#OFFSET2

             ADRL   R3 ,DataArea+4300

;从子程序func返回

             MOV  PC,LR

;从当前位置起保存8000字节存储单元

;并将其初始化为0

DataArea     SPACE    8000

;结束汇编

             END

利用跳转表实现程序跳转实例

;设置本段程序的名称和属性

AREA  JUMP  ,CODE,READONLY

;跳转表中的子程序个数

num   EQU   2

;程序执行的入口点

          ENTRY

start

;设置3个参数,然后调用子程序arithfunc,进行算术运算

          MOV  R0,#0

          MOV  R1,#3

          MOV  R2 ,#2

;调用子程序arithfunc

          BL  arithfunc

stop

;调用angel_SWIreason_ReportException

;ADP_Stopped_ApplicationExit

;ARM semihosting SWI

;从应用程序中退出

          MOV  R0,#0X18

          LDR   R1,=0X20026

          SWI  0X123456

;子程序arithfunc入口点

arithfunc

;判断选择子程序的参数是否在有效范围内

          CMP  R0,#num

          MOVHS  PC, LR

;读取跳转表的基地址

          ADR  R3,JUMPTABLE

;根据参数R0的值跳转到相应的子程序

          LDR  PC,[R3,R0,LSL#2]

;跳转表JUMPTABLE中保存了各个子程序的地址

;在这里有两个子程序DoAdd和DoSub

;当参数R0为0时选择DoAdd

;当参数R0为1时选择DoSub

JUMPTABLE

                DCD  DoAdd

                DCD  DoSub

;子程序DoAdd执行加法操作

DoAdd

            ADD  R0 ,R1,R2

            MOV  PC,LR

;子程序DoSub执行减法操作

DoSub

            SUB  R0,R1,R2

            MOV PC,LR

;结束汇编

            END

伪指令LDR的用法实例

;设置本段程序的名称及属性

AREA    LDRlabel  ,CODE,READONLY

;程序执行的入口点

            ENTRY

start

;跳转到子程序func1及func2执行

            BL   func1

            BL   func2

;调用宏angel_SWIreason_ReportException

;ADP_Stopped_ApplicationExit

;ARM semihosting SWI

;从应用程序中退出

            MOV   R0,#0X18

            LDR    R1,=0X20026

            SWI   0X123456

func1

;下面伪指令被汇编成:LDR  R0,[PC,#OFFSET TO LITPOOL1]

            LDR  R0,=start

;下面伪指令被汇编成:LDR R1,[PC,#OFFSET TO LITPOOL1]

            LDR  R1,=Darea+12

;下面伪指令被汇编成:LDR R2,[PC,#OFFSET TO LITPOOL1]

            LDR  R2,=Darea+6000

;程序返回

            MOV  PC ,LR

;字符缓冲区literal pool 1

            LTORG

func2

;下面的伪指令被汇编成:LDR  R3,[PC,#OFFSET TO LITPOOL 1]

;共有前面的字符缓冲区

            LDR  R3,=Darea+6000

;下面的伪指令如果不注释掉,汇编时会出错

;因为字符缓冲区litpool 2 超出了被伪指令可以到达的范围

             ;LDR R4,=Darea+6004

;程序返回

            MOV  PC ,LR

;从当前地址开始,保留8000字节的存储单元

;并将其内容初始化为0

Darea    SPACE  8000

;字符缓冲区litpool2 应该从这里开始

;它超出了前面被注释掉的伪指令所能够到达的范围

             END

原创粉丝点击