第2章3_ARM汇编程序设计

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。


_start: MOV MOV MOV loop_1: R0 , #0X3000 @初始化寄存器 R1 , #0X10000001 R2 , #100 @第一次循环赋值 R1 , [R0],#4 R1 , R1,#1 R2 , R2,#1 loop_1


STRFra Baidu bibliotekADD SUBS BNE
例 6


用Thumb指令实现内存数据区块拷贝操作。
.global .equ .text _start: .arm _start NUM, 18 @设置要复拷贝的字数


MOV ADR BX
.thumb
SP, #0x9000 R0, Thumb_start + 1 R0

4
汇编语言与C语言混合编程技术
GNU汇编程序基本格式




使用伪操作.equ定义了几个变量并为其赋值。 用伪操作.global声明一个全局变量_strat,在下面 就可以看出, _strat一般用于标识程序代码的开始,即 程序的入口点。 .text伪操作表示以下为代码段,将被编译到代码段 或者代码子段。 .end伪操作汇编编译器源文件的结束。每一个汇编 模块必须包含一个.end伪操作,指示本模块的结束。








.macro mUNSIGN Rd, Rs @ 将一个数无符号 化 TST \Rs, #0x80000000 @ 将无符号的整数放到Rs 中 EORNE \Rd, \Rd, #1 @ 将符号部分放到Rd中 MVNNE \Rs, \Rs ADDNE \Rs, \Rs, #1 .endm .text
;r0 -r1即两数比较 ;r1 > r0,则r1=r1 –r0 ;r0 > r1,则r0=r0 –r1 ;r0 ≠ r1,则转start继续
例3

写一段 ARM汇编程序:循环累加队列中的所有元素,直 到碰上零值元素,结果放在r4。源程序末尾处声明队列: Myarray DCD 0x11 DCD 0x22 DCD 0 r0 指向队列头: ADR r0, myarray 使用命令 LDR r1, [r0], #4来装载,累加至 r4之中,循 环直到r1为0,用死循环来停止。




Division_L1: MOV R5, R5, LSL #1 CMP R0, R1 @ 判断是否够减 SUBGT R0, R0, R1 @ 如果够减,做减法,上商1 ORRGT R5, R5, #1 SUBS R3, R3, #1 MOVCS R1, R1, LSR #1 BCS Division_L1 Division_L2: TST R6, #1 @ 处理结果的符号 MVNNE R5, R5 ADDNE R5, R5, #1 Division_F: MOV R1, R0 MOV R0, R5


ADR LDR 的子程序 Jtable DCD DCD DoAdd ADD MOV DoSub SUB MOV END
R3,JTable ;读取跳转表的基地址 PC,[R3,R0,LSL #2] ;根据R0的值跳转到相应
DoAdd DoSub
;当R0为0时上面的代码将跳转到DoAdd ;当R0为1时上面的代码将跳转到DoSub ;子程序DoAdd执行加法操作 ;子程序返回 ;子程序DoAdd执行减法操作 ;子程序返回 ;结束汇编
(2) 注释 GNU ARM Assembly可识别的注释方式有:C风格 多行注释符/* ... */或GNU单行注释符‚@‛或 ‚#‛。 (3) 符号 与C语言基本一致,符号名由字母、数字以及'_'、 和'.'组成,大小写敏感。
段与重定位 链接器ld用于把多个目标文件合并为一个可执行 文件。汇编器as生成的目标文件都假定从地址0 开始,ld为其指定最终的地址。链接器ld把目 标文件中的每个section都作为一个整体,为其 分配运行的地址
本章提要
汇编语言源程序格式
1
2
汇编语言程序设计实例
3
嵌入式C语言程序设计技巧
4
汇编语言与C语言混合编程技术
ARM汇编语言程序设计实例解析
数据块复制 两数中大者减小者直到零
累加队列中所有数
利用跳转表实现程序跳转 整数除法
例1

先对内存地址0x3000开始的100个字内 存单元填入0x10000001~0x10000064字 数据,然后将每个字单元进行64位累加 结果保存于[R9:R8]。(R9中存放高32位)




_start: LDR R0, =-123456 @ 被除数 LDR R1, =523 @ 除数 Div: MOV R6, #0 @ 结果的符号位 mUNSIGN R6, R0 @ 无符号化 mUNSIGN R6, R1 MOV R5, #0 @商 CMP R0, R1 @ 如果被除数小于除数 BLT Division_L2 @ 直接商0 mCLZ R3, R1 @ 判断除数位数,确定移位情况 SUB R3, R3, #1 MOV R1, R1, LSL R3


源程序如下: AREA total, CODE ENTRY MOV r4, #0 ADR r0, array loop LDR r1,[r0], #4 ADD r4, r4, r1 CMP r1, #0 BNE loop stop B stop Array DCD 0x11 DCD 0x22 DCD 0 END
R0,R1,R2 PC,LR R0,R1,R2 PC,LR
例 5

实现整数除法,整数用补码表示。先将被除数和除数高 位对齐,如果够减上商1,并减去除数;否则上商0。然后 右移除数1位,重复上述操作。
.global _start .macro mCLZ Rd, Rs @ 求一个数的前导0个数 MOV \Rd, #0 @ 在某些ARM中,可使用指令CLZ代 替 __mCLZ_L1: TST \Rs, #0x80000000 ADDEQ \Rd, \Rd, #1 MOVEQ \Rs, \Rs, ROR #31 @ 左移一位 BEQ __mCLZ_L1 MOV \Rs, \Rs, LSR \Rd .endm



例2

用ARM指令编写程序,将两数中的大 数减小数直至减到结果为0为止。
程序如下: .text _start: MOV MOV CMP SUBLT SUBGT BNE stop B END
r0, #9 r1, #15 r0, r1 r1, r1, r0 r0, r0, r1 start stop

Thumb_start: LDR LDR MOV LSR
BEQ PUSH
R0, =Src @R0 = 源数据区指针 R1, =Dst @R1 = 目标数据区指针 R2, #NUM R3, R2, #2 @获得块拷贝的次数 Copy_Words {R4-R7} @保存将要使用的寄存器R4-R7
符号说明 (1)label lable后面要带冒号‘:’ 例如:_start: b reset_handler。
(2)给符号赋值 三种方式:= .set .equ (3)符号名 由数字、字母或‚.‛,‚_‛组成,不可以数字 开头,大小写敏感。
汇编器预定义的寄存器名称
R0~R15 A1~A4 V1~V8 SB SL FP IP SP LR PC CPSR SPSR F0~F7 S0~S31 D0~D15 P0~P15 C0~C15 ARM 处理器的通用寄存器 入口参数、处理结果、暂存寄存器;是 R0~R3 的同义词 变量寄存器,R4~R11 静态基址寄存器,R9 栈界限寄存器,R10 帧指针寄存器,R11 内部过程调用暂存寄存器,R12 栈指针寄存器,R13 链接寄存器,R14 程序计数器,R15 当前程序状态寄存器 程序状态备份寄存器 浮点数运算加速寄存器 单精度向量浮点数运算寄存器 双精度向量浮点数运算寄存器 协处理器 0~15 协处理器寄存器 0~15
第二章_3 ARM汇编程序设计

在ARM嵌入式系统中,一般用C语言等高级语言对 各个应用接口模块功能的实现进行程序设计,但在 某些地方用汇编语言更方便、简单。 在一些关键部分,例如用来初始化电路以及用来为 软件(高级语言编写)做运行前准备的启动代码必 须用汇编语言编写。


汇编语言的代码效率很高,一般用于对硬件的直接 控制。
;设置初始值
;基址指针 r0自动增加
;r1为0时中断循环 ;死循环 ;声明队列
例4



利用跳转表实现程序跳转。 在程序中常需要根据一定的参数选择执行不同的子程 序。本例跳转表中存放的是各子函数的地址,选择不同 的子程序的参数是该子程序在跳转表中的偏移量。在本 例中,R3寄存器中存放的是跳转表的基地址,即存放子 程序的入口地址的跳转表的首地址。 R0寄存器的值用于选择不同的子程序:当R0为0时, 选择的是子程序DoAdd;当R0为1时,选择的是子程序 DoSub。

MOV MOV MOV MOV loop_2:


LDR ADDS
位 ADC SUBS BNE
R0 , #0X3000 R2 , #100 R9 , #0 R8 , #0 @第二次循环累加 R1 , [R0],#4 R8 , R1,R8 @R8=R8+R1,进位影响标志 R9 , R9 , #0 @R9=R9+C,C为进位 R2 , R2 , #1 loop_2
[标签:] 指令/伪操作/伪指令 操作数 [@语句的注释]
GNU环境下ARM汇编程序编译
基本语法 (1) 预处理 GNU汇编器as的内部预处理包括:移除多余 的间隔符代码中的所有注释,并将字符常量转换 为数字值。它不作宏处理和文件包含处理,但这 些事情可以交由gcc编译器去做,文件包含可以 用.include伪指令来实现。



GNU环境下汇编语句与编译说明
GNU环境下ARM汇编语言程序设计主要 是面对在ARM平台上进行嵌入式LINUX的开发。 GNU标准中提供了支持ARM汇编语言的 汇编器as(arm-elf-as)、交叉编译器gcc ld(arm-elfgcc)和链接器ld(arm-elf-ld)。
GNU环境下ARM汇编语言语句格式如下:
二、ARM编译环境下汇编语句



.global _start .equ x,30 .equ y,40 .text _start: mov sp,#0x00000800 mov r0,#x mov r1,#y add r2,r0,r1 str r2,[sp] stop: b stop .end



在ADS编译环境下,程序如下: AREA Jump,CODE,READONLY ;设置本段程序的名称及属性 NUM EQU 2 ;跳转表中的子程序个数 ENTRY ;程序执行的入口点 Start MOV R0, #0 ;设置参数,R0中为需调用哪个子程序 MOV R1, #3 ; R1为子程序要用的参数 MOV R2, #2 ; R2为子程序要用的参数 BL Func ;调用子程序Func,进行算术运算 stop MOV R0, #0x18 ;软中断参数设置 LDR R1, =0x20026 ;软中断参数设置 SWI 0x123456 ;将CPU的控制权交给调试器 Func CMP R0,#NUM ;判断R0是否在有效范围之内 MOVHS PC,LR ;如果超出范围则程序返回
编程步骤 1 分析问题 2 确定算法 3 确定数据分配的存储单元 4 画程序流程图 5 编写程序
ARM源程序文件
文件类型
汇编语言源文件 C语言源文件 C++源文件 引入文件 头文件
扩展名
.s .c .cpp .INC .h
本章提要
1 GNU汇编语言源程序格式
2
汇编语言程序设计实例
3
嵌入式C语言程序设计技巧
相关文档
最新文档