首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM程序设计举例

ARM程序设计举例

3.8  ARM程序设计举例3.8.1  分支程序程序设计中的三种基本结构是:顺序结构、分支结构和循环结构。在C语言中可以使用if-else语句实现单分支和双分支结构,也可以通过switch-case语句实现多分支结构。但是在汇编语言中,分支结构一般是通过跳转指令结合标号来实现的。
ARM汇编语言程序中,由于ARM指令支持条件执行,从而大大减少了分支程序的复杂程度。
例如:用两个整数辗转相减的方法求它们的最大公约数。注意体会B指令加条件码的执行方式。程序中使用的main标号是因为IAR汇编器一般默认从main标号处开始执行。
代码清单3.2
NAME GCD
PUBLIC  main                         ;声明外部引用标号main
B      main ;main标号处开始执行
RSEG CODE:CODE                           
CODE32                              
main: MOV R0,#120
MOV R1,#96
Gcd: CMP R0,R1 ;比较两数的大小
BEQ Stop ;如果两数相等则跳到结束处
BLT Less ;如果R0<R1则跳到Less标号处
SUB R0,R0,R1 ;否则R0=R0-R1
B Gcd
Less: SUB R1,R1,R0 R1=R1-R0
B Gcd
Stop: B Stop ;跳转到指令本身,程序停止运行
ENDMOD ;本程序模块结束
END ;本程序结束
3.8.2  循环程序通过跳转指令还可以实现程序的循环结构。
例如:求n=1+2+…+10累加的和。
代码清单3.3
NAME SUM
PUBLIC  main                        
B       main
RSEG CODE                           
CODE32                              
main: MOV R0,#10
MOV R1,R0 ;利用R1寄存器做循环计数器
Loop: SUBS R1,R1,1 ;循环次数减1
ADD   R0,R0,R1
BNE Loop ;循环次数为0则结束循环
Stop: B Stop
ENDMOD
END
3.8.3  子程序调用通过BL指令可以实现子程序调用,语法:BL子程序名。
在子程序的结束处,可以通过MOV  PCLR返回到主程序中。通常可以使用寄存器R0R3完成传递参数到子程序和从子程序返回运算的结果。
以下是使用BL指令调用子程序的汇编语言源程序的例子,该程序编写了一个在内存里拷贝字符串的子程序,然后在主程序里调用它。
代码清单3.4
       NAME  STRCPY                        
        PUBLIC  main                        
        B       main
        RSEG CODE                           
        CODE32                              
main LDR R1,=srcstr       ;R1指向源字符串
       LDR R0,=dststr  ;R0指向目标字符串
  BL strcopy  ;调用strcopy子程序
stop:   B stop  ;程序停止
strcopy:  ;子程序定义
        LDRB R2,[R1],#1   ;读一个字符到R2,并更新源字符地址
        STRB R2,[R0],#1   ;写一个字符,并更新目的字符地址
        CMP R2,#0  ;是否结束。以数字0为标志
        BNE strcopy   ;循环执行

        DATA  ;数据区
srcstr DCB "First string - source ",0
dststr DCB "Second string - destination ",0
        ENDMOD                              
        END        
3.8.4  查表法查表法是编程中常用的一种技巧。当程序涉及到较多的数据、数据串或数据表格时,可以通过地址来对它们进行访问。通常有两种方法装载地址:(1)通过ADRADRL伪指令直接装载地址;(2)通过伪指令LDR Rd,=Label从数据表格中装载地址。
下面的程序设置了3个参数,arithfunc根据3个参数返回一个R0值。当R0=0时,R0=R1+R2;当R0=1时,R0=R1-R2;当R0>1时,R0=R1+R2。:
代码清单3.5
      NAME  JUMP                        
        PUBLIC  main                        
        B       main
   Num  EQU 2 ;跳转表格的入口数
        RSEG CODE                           
        CODE32                              
main  MOV  R0,#0        ;以下设置3个参数
        MOV R1,#3  
   MOV R2,#2
   BL arithfunc   ;调用子程序
stop:    B stop ;程序停止
arithfunc:  
        CMP R0,#Num   ;比较参数
        BHS Doadd  ;R0>=2,则执行加法
        ADR R3,jumptable   ;装载跳转表格标号地址
        LDR PC,[R3,R0,LSL #2]   ;跳到相应子程序入口地址处
Jumptable:
        DCD Doadd   ;Doadd子程序的入口地址
        DCD Dosub   ;Dosub子程序的入口地址
Doadd:  ADD R0,R1,R2   ;=0>1时执行的操作
   MOV PC,LR
Dosub:  SUB R0,R1,R2   ;=1时执行的操作
   MOV PC,LR
        ENDMOD                              
        END
返回列表