ARM指令——跳转指令

目录

一、跳转指令

方式一:直接修改PC寄存器的值(不建议使用,需要自己计算目标指令的绝对地址)

方式二:不带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下指令的地址

方式三:带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下指令的地址,同时将跳转指令下一条指令的地址存储到LR寄存器

C语言的函数调用

 二、ARM指令的条件码

2.1比较指令

 2.2ARM指令集中大多数指令都可以带条件码后缀

2.3练习:用汇编语言实现以下逻辑

三、Load/Srore指令:访问(读写)内存

 3.1写内存

3.2读内存

3.3读/写指定的数据类型

四、ARM指令的寻址方式

4.1立即寻址

4.2寄存器寻址

        4.3寄存器移位寻址

4.4寄存器间接寻址

4.5基址加变址寻址

4.6基址加变址寻址的索引方式

        4.6.1前索引

4.6.2后索引

4.6.3自动索引


一、跳转指令

实现程序的跳转本质上就是修改了PC寄存器的值

一般一个函数编译成的汇编指令在内存中是连续的

方式一:直接修改PC寄存器的值(不建议使用,需要自己计算目标指令的绝对地址)


@ MAIN:
        @ MOV R1, #1
        @ MOV R2, #2
        @ MOV R3, #3
        @ MOV PC, #0x18
        @ MOV R4, #4
        @ MOV R5, #5    
@ FUNC:
        @ MOV R6, #6
        @ MOV R7, #7
        @ MOV R8, #8


方式二:不带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下指令的地址

@ MAIN:
        @ MOV R1, #1
        @ MOV R2, #2
        @ MOV R3, #3
        @ B   FUNC
        @ MOV R4, #4
        @ MOV R5, #5    
@ FUNC:
        @ MOV R6, #6
        @ MOV R7, #7
        @ MOV R8, #8
        


方式三:带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下指令的地址,同时将跳转指令下一条指令的地址存储到LR寄存器


@ MAIN:
        @ MOV R1, #1
        @ MOV R2, #2
        @ MOV R3, #3
        @ BL  FUNC
        @ MOV R4, #4
        @ MOV R5, #5    
@ FUNC:
        @ MOV R6, #6
        @ MOV R7, #7
        @ MOV R8, #8
        @ MOV PC, LR
        @ 程序返回

 

 

C语言的函数调用

 

 二、ARM指令的条件码

 

2.1比较指令

@ CMP指令的本质就是一条减法指令(SUBS),只是没有将运算结果存入目标寄存器


        @ MOV R1, #1
        @ MOV R2, #2
        @ CMP R1, R2
        @ BEQ FUNC    
        @ 执行逻辑:if(EQ){B FUNC}    本质:if(Z==1){B FUNC}
        @ BNE FUNC    
        @ 执行逻辑:if(NE){B FUNC}    本质:if(Z==0){B FUNC}
        @ MOV R3, #3
        @ MOV R4, #4
        @ MOV R5, #5
@ FUNC:
        @ MOV R6, #6
        @ MOV R7, #7

R1 和 R2不相等,并没有跳转,相等时发生跳转

 换成BNE跳不了了

 2.2ARM指令集中大多数指令都可以带条件码后缀


        @ MOV R1, #1
        @ MOV R2, #2
        @ CMP R1, R2
        @ MOVGT R3, #3
        

 

C语言翻译成汇编


 

2.3练习:用汇编语言实现以下逻辑


            @ int R1 = 9;
            @ int R2 = 15;
        @ START:
            @ if(R1 == R2)
            @ {
            @     STOP();
            @ }
            @ else if(R1 > R2)
            @ {            
            @     R1 = R1 - R2;
            @     goto START;
            @ }
            @ else
            @ {
            @     R2 = R2 - R1;
            @    goto START;
            @ }
        

 我的答案比较笨,也许是病没好的事

.text
.global _start
 
_start:

    MOV R1, #9
    MOV R2, #15
START:
    CMP R1, R2
    BEQ STOP
    BHI FUNC
    SUB R2, R2, R1
    B START
STOP:
    B STOP
FUNC:
    SUB R1, R1, R2
    B START
    
.end

 老师的就简便多了

@ 练习答案
        MOV R1, #9
        MOV R2, #15
START:
        CMP R1,R2
        BEQ STOP
        SUBGT R1, R1, R2
        SUBLT R2, R2, R1
        B START
STOP:                
        B STOP

三、Load/Srore指令:访问(读写)内存


    一般LD开头的指令将指令从内存读到CPU,ST开头的指令将CPU的指令拿到内存。

在debug模式下单击Memory map,可以告诉我们当前芯片每段的权限

 


 3.1写内存


        @ MOV R1, #0xFF000000
        @ MOV R2, #0x40000000
        @ STR R1, [R2] 
        @ 将R1寄存器中的数据写入到R2指向的内存空间

同时验证了ARM是小端对齐的 

数据是几个字节数据的起始地址就是几的整数倍

3.2读内存


        @ LDR R3, [R2]
        @ 将R2指向的内存空间中的数据读取到R3寄存器
        

3.3读/写指定的数据类型


        @ MOV R1, #0xFFFFFFFF
        @ MOV R2, #0x40000000
        @ STRB R1, [R2]
        @ 将R1寄存器中的数据的Bit[7:0]写入到R2指向的内存空间
        @ STRH R1, [R2]     
        @ 将R1寄存器中的数据的Bit[15:0]写入到R2指向的内存空间
        @ STR  R1, [R2]     
        @ 将R1寄存器中的数据的Bit[31:0]写入到R2指向的内存空间
        
        @ LDR指令同样支持以上后缀


     

四、ARM指令的寻址方式

寻址方式就是CPU去寻找操作数的方式
        

4.1立即寻址


        @ MOV R1, #1
        @ ADD R1, R2, #1
        

4.2寄存器寻址


        @ ADD R1, R2, R3


        
4.3寄存器移位寻址


        @ MOV R1, R2, LSL #1
        

4.4寄存器间接寻址


        @ STR R1, [R2] 
        



4.5基址加变址寻址


        @ MOV R1, #0xFFFFFFFF
        @ MOV R2, #0x40000000
        @ MOV R3, #4
        @ STR R1, [R2,R3]
        @ 将R1寄存器中的数据写入到R2+R3指向的内存空间(以R2为基地址偏移R3的数量)
        @ STR R1, [R2,R3,LSL #1]
        @ 将R1寄存器中的数据写入到R2+(R3<<1)指向的内存空间

4.6基址加变址寻址的索引方式


        
4.6.1前索引


        @ MOV R1, #0xFFFFFFFF
        @ MOV R2, #0x40000000
        @ STR R1, [R2,#8]
        @ 将R1寄存器中的数据写入到R2+8指向的内存空间
        


4.6.2后索引


        @ MOV R1, #0xFFFFFFFF
        @ MOV R2, #0x40000000
        @ STR R1, [R2],#8
        @ 将R1寄存器中的数据写入到R2指向的内存空间,然后R2自增8
        


4.6.3自动索引


        @ MOV R1, #0xFFFFFFFF
        @ MOV R2, #0x40000000
        @ STR R1, [R2,#8]!
        @ 将R1寄存器中的数据写入到R2+8指向的内存空间,然后R2自增8
        
        @ 以上寻址方式和索引方式同样适用于LDR

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇努力学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值