ARM汇编

这两天参加了一个编写操作系统的项目,因为要做很多底层的东西,而且这个操作系统是嵌入式的,所以开始学习ARM汇编,发现ARM汇编和一般PC平台上的汇编有很多不同,但主要还是关键字和伪码上的,其编程思想还是相同的。现将一些学习感悟部分列出来,希望能给有问题的人一点帮助。

    1、ARM汇编的格式:
    在ARM汇编里,有些字符是用来标记行号的,这些字符要求顶格写;有些伪码是需要成对出现的,例如ENTRY和END,就需要对齐出现,也就是说他们要么都顶格,要么都空相等的空,否则编译器将报错。常量定义需要顶格书写,不然,编译器同样会报错。
    2、字符串变量的值是一系列的字符,并且使用双引号作为分界符,如果要在字符串中使用双引号,则必须连续使用两个双引号。
    3、在使用LDR时,当格式是LDR r0,=0x022248,则第二个参数表示地址,即0x022248,同样的,当src变量代表一个数组时,需要将r0寄存器指向src则需要这样赋值:LDR r0,=src     当格式是LDR r0,[r2],则第二个参数表示寄存器,我的理解是[]符号表示取内容,r2本身表示一个寄存器地址,取内容候将其存取r0这个寄存器中。
    4、在语句:
       CMP r0,#num
       BHS stop
       书上意思是:如果r0寄存器中的值比num大的话,程序就跳转到stop标记的行。但是,实际测试的时候,我发现如果r0和num相等也能跳转到stop标记的行,也就是说只要r0小于num才不会跳转。
    
     下面就两个具体的例子谈谈ARM汇编(这是我昨天好不容易看懂的,呵呵)。
     第一个是使用跳转表解决分支转移问题的例程,源代码如下(保存的时候请将文件后缀名改为s):   

      AREA JumpTest,CODE,READONLY
      CODE32
 num  EQU  4

 ENTRY
 
start
      MOV  r0, #4
      MOV  r1, #3
      MOV  r2, #2
      MOV  r3, #0
 
      CMP  r0,  #num
      BHS  stop
 
      ADR  r4, JumpTable
 
      CMP  r0, #2
      MOVEQ  r3, #0
      LDREQ  pc, [r4,r3,LSL #2]
 
      CMP  r0, #3
      MOVEQ  r3, #1
      LDREQ  pc, [r4,r3,LSL #2]
 
      CMP  r0, #4
      MOVEQ  r3, #2
      LDREQ  pc, [r4,r3,LSL #2]
 
      CMP  r0, #1
      MOVEQ  r3, #3
      LDREQ  pc, [r4,r3,LSL #2]
 
DEFAULT
      MOVEQ  r0, #0
 
SWITCHEND

stop
      MOV  r0, #0x18
      LDR  r1, =0x20026
      SWI  0x123456
 
JumpTable
      DCD  CASE1
      DCD  CASE2
      DCD  CASE3
      DCD  CASE4
      DCD  DEFAULT
 
CASE1
      ADD  r0, r1, r2
      B  SWITCHEND
 
CASE2
      SUB  r0, r1, r2
      B  SWITCHEND
 
CASE3
      ORR  r0, r1, r2
      B  SWITCHEND
 
CASE4
      AND  r0, r1, r2
      B  SWITCHEND
 END 
    程序其实很简单,可见我有多愚笨!还是简要介绍一下这段代码吧。首先用AREA伪代码加上CODE,表明下面引出的将是一个代码段(于此相对的还有数据段DATA),ENTRY 和END成对出现,说明他们之间的代码是程序的主体。start段给寄存器初始化。ADR  r4, JumpTable一句是将相当于数组的JumpTable的地址付给r4这个寄存器。

    stop一段是用来是程序退出的,第一个语句“MOV r0,#0x18”将r0赋值为0x18,这个立即数对应于宏angel_SWIreason_ReportException。表示r1中存放的执行状态。语句“LDR r1,=0x20026”将r1的值设置成ADP_Stopped_ApplicationExit,该宏表示程序正常退出。然后使用SWI,语句“SWI 0x123456”结束程序,将CPU的控制权交回调试器手中。

    在JumpTable表中,DCD类型的数组包含四个字,所以,当实现CASE跳转的时候,需要将给出的索引乘上4,才是真正前进的地址数。

 

    再看一个用汇编实现冒泡排序的例程:

     AREA Sort,CODE,READONLY
 ENTRY
 
start
     MOV r4,#0
     LDR r6,=src
     ADD r6,r6,#len
 
outer
     LDR r1,=src
 
inner
     LDR r2,[r1]
     LDR r3,[r1,#4]
     CMP r2,r3
     STRGT r3,[r1]
     STRGT r2,[r1,#4]
     ADD r1,r1,#4
     CMP r1,r6
     BLT inner
 
     ADD r4,r4,#4
     CMP r4,#len
     SUBLE r6,r6,#4
     BLE outer
 
stop
     MOV r0,#0x18
     LDR r1,=0x20026
     SWI 0x123456
 
     AREA Array,DATA,READWRITE
src DCD 2,4,10,8,14,1,20
len EQU 7*4
     END

     用汇编实现循环需要跳转指令,但是因为ARM系统只有一个CPSR寄存器,所以要实现双重循环还是有些难度。上面这个代码还是有相当大的借鉴意义。程序不难读懂,和C语言的冒泡排序基本思路是完全一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值