ARM体系结构与接口技术——ARM指令集


ARM汇编框架

xx.s

.text        @表示当前为代码段
.global _start        @将_start定义成全局符号
_start:        @汇编的入口

    MOV R1,#1
    MOV R2,#2
    MOV R3,#3

.end        @汇编的结束

ARM汇编概述

汇编中的符号

  1. 指令:能够编译成一条32位的机器码,并且能被CPU识别和执行。
  2. 伪指令:本身不是指令,编译器可以将其替换成若干条指令
  3. 不会生成指令,只是在编译阶段告诉编译器怎么编译,类似C语言的条件编译

ARM的指令

  1. 数据处理指令:进行数学运算、逻辑运算
  2. 跳转指令:实现程序的跳转,本质就是修改PC寄存器
  3. Load/Store指令:访问(读写)内存
  4. 状态寄存器传送指令:用于访问(读写)CPSR寄存器
  5. 软中断指令:触发软中断
  6. 协处理器指令:操作协处理器的指令

指令基本格式

  <操作码> <目标寄存器>, <第一操作寄存器>, <第二操作数>


 

ARM指令集

数据处理指令
.text
.global _start
_start:

    @ 数据搬运指令
    MOV R1,#1        @把一个数搬运到一个寄存器
    MOV R2,R1        @从一个寄存器搬运到另一个寄存器
    MVN R0,#0xFF    @按位取反再搬运
    
    @ MOV PC,#0        @搬运一个数到PC寄存器,程序会跳转
    
    @ 立即数,本质是包含在指令中的数,属于指令的一部分
    @ 所以立即数不能太大,范围在0-255之间。
    @ MOV R0, #0x12345678    @0x12345678这不是立即数,不能被编译成功
    
    @ 0xFFFFFFFF这不是立即数,但是能被编译成功
    @ 这一条是伪指令,编译器会把他替换成同样效果的指令。
    MOV R0, #0xFFFFFFFF    @ MVN R0,#0x00
    
    @ 加法指令
    ADD R3,R1,R2    @ R3 = R1 + R2
    ADD R3,R2,#5    @ R3 = R2 + 5
    @ 不合法的指令
    @ ADD R3,#5,R2    @第一寄存器不能放数
    
    @ 减法指令
    SUB R1,R2,R3    @ R1 = R2 - R3
    RSB R1,R2,#3    @ R1 = 3 - R2    逆向减法指令
    
    @ 乘法指令
    MUL R1,R2,R3    @ R1 = R2 * R3
    
    @ 按位与
    AND R1,R2,R3    @ R1 = R2 & R3
    
    @ 按位或
    ORR R1,R2,R3    @ R1 = R2 | R3
    
    @ 按位异或
    EOR R1,R2,R3    @ R1 = R2 ^ R3
    
    @ 移位
    LSL R1,R2,R3    @ R1 = R2 << R3,    R2左移R3位,给R1
    LSR R1,R2,R3    @ R1 = R2 >> R3,    R2右移R3位,给R1
    
    @ 位清零
    BIC R1, R2, #0xF
    @ 第二操作数(0xF)中的哪一位,就将第一操作寄存器中的哪一位清零,然后放入目标寄存器
    
    
    @ 数据运算指令的格式扩展
    MOV R1,R2,LSL #1    @ R1 = (R2 << 1)

    @ 数据运算指令对条件位的影响,CPSR NZVC
    @ 默认情况下数据运算不会对条件为产生影响,当指令加后缀S后可以影响
    MOV R1,#3
    SUBS R2,R1,#5
    
    @ 两个64位的数据做加法运算
    @ 0x00000001 FFFFFFFF
    @ 0x00000002 00000005
    
    MOV R1,#0xFFFFFFFF
    MOV R2,#0x00000001
    MOV R3,#0x00000005
    MOV R4,#0x00000002
    
    ADDS R5,R1,R3    @溢出时条件位溢出位会自动置1
    ADC R6,R2,R4    @ R6 = R2 + R4 + 'C',在执行的过程中,会把条件位的溢出位加上
    
    @ 带借位的减法指令
    @ 0x00000002 00000001
    @ 0x00000001 00000005
    MOV R1,#0x00000001
    MOV R2,#0x00000002
    MOV R3,#0x00000005
    MOV R4,#0x00000001
    
    SUBS R5,R1,R3
    SBC R6,R2,R4
    @ 本质: R6 = R2 - R4 - '!C',即执行的过程中,会把条件位的溢出位取反再减
    
    
stop:
    B stop
    

.end


 

跳转指令
.text
.global _start
_start:

    
    @ 方式一:直接去修改PC寄存器的值
    @ MOV R1,#1
    @ MOV R2,#2
    @ MOV R3,#3
    @ MOV PC,#0x18
    @ MOV R4,#4        @ 这条指令被跳过
    
    @ MOV R6,#6
    
    
    @ 方式二:通过跳转指令B
    @ 本质也是修改PC
    @ MOV PC,LR 跳转失败,它会跳转回:跳转指令,因为B跳转指令,没有保存返回地址给LR
@MAIN:
@    MOV R1,#1
@    B FUNC
@    MOV R2,#2
@    MOV R3,#3
@FUNC:
@    MOV R4,#4
@    MOV PC,LR
    
    @ 方式三:通过跳转指令BL
    @ 跳转的同时,会修改CPSR的跳转状态位的值,并且保存返回的地址给LR
MAIN:
    MOV R1,#1
    MOV R2,#2
    BL FUNC
    MOV R3,#3
    MOV R4,#4
FUNC:
    MOV R5,#5
    MOV PC,LR
    
stop:
    B stop
.end

 

ARM条件码(不算指令)
@条件码
.text
.global _start
_start:

MAIN:
    MOV R1,#1
    MOV R2,#1
    
    @比较指令
    CMP R1,R2    @没有目标寄存器,结果自动存储在状态寄存器CPSR的NZCV
    @本质就是一条减法指令,SUBS,只是没有将运算的结果存入寄存器
    @如果R1==R2,Z=1,产生0
    @如果R1!=R1,Z=0
    @如果R1<R2,Z=0且C=0,产生了借位
    @如果R1<=R2,C=0或Z=1
    @如果R1>R2,C=1且Z=0
    @如果R1>=R2,C=1或Z=1
    
    BEQ FUNC    @EQ是一个条件码助记符后缀,大多数指令都可以加后缀
    MOV R3,#3    @该条指令会被跳过
FUNC:
    MOV R4,#4    @程序会跳转到这里

.end

ARM条件码和助记符后缀

ARM体系结构与接口技术——ARM指令集


ARM内存访问指令

内存访问指令1

@内存访问指令
.text
.global _start
_start:

    @ 写内存
    MOV R1,#0xFFFFFFFF
    MOV R2,#0x40000000    @0x40000000 是可读可写的内存地址
    @STR R1,[R2]        @把R1寄存器中的数据存储到R2指向的内存空间4个字节
    STRB R1,[R2]        @把R1寄存器中的数据存储到R2指向的内存空间
    
    @ 读内存
    LDR R3,[R2]        @把R2指向的内存空间的数据读取到R3


.end

 

ARM指令的寻址方式

@ ARM寻址方式

.text
.global _start
_start:

    @ 方式一:立即寻址
    @ 回顾一下立即数,立即寻址即直接使用指令机器码中的立即数
    MOV R1,#1
    ADD R1,R2,#1
    
    @ 方式二:寄存器取址
    ADD R1,R2,R3
    
    @ 方式三:寄存器移位寻址
    MOV R1,R2, LSL #1
    
    @ 方式四:寄存器间接寻址
    STR R1, [R2]
    
    @...还有很多,ARM一共九种

.end

内存访问指令2

@ 内存访问指令2
@ 基于ARM指令的寻址方式
@ 基址加变址寻址

.text
.global _start
_start:


    MOV R1, #0xFFFFFFFF
    MOV R2, #0x40000000
    MOV R3, #4
    
    @ 前索引:
    @STR R1, [R2,#4]
    @ 将R1寄存器中的数据写入到R2+4指向的内存空间:0x40000004
    @ R2的值并不会改变,对比自动索引
    
    @STR R1, [R2,R3]
    @ 将R1寄存器中的数据写入到R2+R3指向的内存空间:0x40000004
    
    @STR R1, [R2,R3,LSL #1]
    @ 将R1寄存器中的数据写入到R2+(R3<<1)指向的内存空间:0x40000008

@*****************************************************************
    
    
    @ 后索引:
    STR R1, [R2], #8
    @ 将R1寄存器中的数据写入到R2指向的内存空间:0x40000000
    @ 然后R2自增8
    
    
    @ 自动索引:
    STR R1, [R2,#8]!
    @ 将R1寄存器中的数据写入到R2+8指向的内存空间:0x40000008
    @ 然后R2自增8
    

.end

 

 

 


 

END 

原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/245367.html

(0)
上一篇 2022年4月18日
下一篇 2022年4月18日

相关推荐

发表回复

登录后才能评论