您的位置:首页 > 编程语言

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

2013-03-29 15:37 246 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: