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

编器将文字池放在每节的末尾。 这些节的末尾是由下一节开始处的 AREA 指令定义的,或者是由汇编代码末尾的 END 指令定义的。位于所包含的文件末尾的 END 指令并不表示一节的结束 

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(为SWI调用准备参数)

             LDR   R1,=0X20026           ;将0X20026 赋值给R1,0X20026 立即数对应宏ADP_Stopped_ApplicationExit,表示程序正常退出(准备调用SWI的ADP_Stopped_ApplicationExit)          SWI   0X123456                 ;结束程序,将控制权交给调试器(semihosting软中断调用)

应用程序终止:在执行主代码后,应用程序会将控制权返回给调试器,以此来终止执行,此操作是通过将ARM半主机SVC(缺省为0X123456)与下列参数结合使用来完成的,R0=0x18.r1=0x20026

;定义一个数据缓冲区,用于生成地址标号相对于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

 

你可能感兴趣的:(编程,汇编,存储)