《ARM汇编编程:基础指令集入门》

ARM汇编基础指令集

  • 一、Cortex-A 的内核寄存器组
  • 二、赋值指令 MOV、LDR
  • 1、MOV
  • 2、LDR
  • 三、算数指令 ADD、SUB、MUL
  • 1、ADD加法
  • 2、SUB减法
  • 3、MUL乘法
  • 四、移位指令 LSL、LSR
  • 1、LSL左移位
  • 2、LSR右移位
  • 五、逻辑位指令 AND、ORR、MVN、EOR
  • 1、AND与
  • 2、ORR或
  • 3、MVN非
  • 4、EOR异或
  • 六、跳转指令 B、BL
  • 1、B直接跳转
  • 2、BL暂存当前位置后直接跳转
  • 七、比较指令 CMP:EN、EQ、GT、LT、GE、LE
  • 八、单个内存读写指令 LDR、STR
  • 1、LDR 读取内存的地址
  • 2、STR 写入内存的地址
  • 九、多个内存读写指令 STM、LDM
  • 1、STM
  • 2、LDM
  • 一、Cortex-A 的内核寄存器组


    Cortex-A 的内核寄存器组


  • 二、赋值指令 MOV、LDR

    1、MOV

    MOV 目标寄存器 , 立即数

    MOV R0,#1 			;为寄存器R0赋值,值为1
    

    2、LDR

    LDR 目标寄存器 , = 赋值数

    LDR R0,=0xAB00CD 	;为寄存器R0赋值,值为0xAB00CD
    

  • 三、算数指令 ADD、SUB、MUL

    注意:运算符只能为 A+B(两个参数),A+B+…超过两个是不允许的

    1、ADD加法

    ADD 目标寄存器 , 寄存器1 , 寄存器2(也可以是立即数)

    ADD R0,R0,R1 		;*R0 = *R0 + *R1
    ADD R0,R0,#10 		;*R0 = *R0 + 10
    

    2、SUB减法

    SUB 目标寄存器 , 寄存器1 , 寄存器2(也可以是立即数)

    SUB R0,R0,R1 		;*R0 = *R0 - R1
    SUB R0,R0,#10 		;*R0 = *R0 - 10
    

    3、MUL乘法

    MUL 目标寄存器 , 寄存器1 , 寄存器2(也可以是立即数)

    MUL R0,R0,R1 		;*R0 = *R0 * R1
    MUL R0,R0,#10 		;*R0 = *R0 * 10
    

  • 四、移位指令 LSL、LSR

    1、LSL左移位

    MOV 目标寄存器 , 寄存器1 , LSL 立即数

    MOV R0,R1,LSL #4 		;*R0 = *R1 << 4
    

    2、LSR右移位

    MOV 目标寄存器 , 寄存器1 , LSR 立即数

    MOV R0,R1,LSR #4 		;*R0 = *R1 >> 4
    

  • 五、逻辑位指令 AND、ORR、MVN、EOR

    1、AND与

    AND 目标寄存器 , 寄存器1 , 寄存器2(也可以是立即数)

    AND R0,R0,R1			;*R0 = *R0 & *R1
    AND R0,R0,#0X0F			;*R0 = *R0 & 0X0F
    

    2、ORR或

    ORR 目标寄存器 , 寄存器1 , 寄存器2(也可以是立即数)

    ORR R0,R0,R1			;*R0 = *R0 | *R1
    ORR R0,R0,#0X0F			;*R0 = *R0 | 0X0F
    

    3、MVN非

    将 操作2 取反的值给目标寄存器

    MVN 目标寄存器 , 寄存器2(也可以是立即数)

    MVN R0,R1				;*R0 = ~*R1
    MVN R0,#0X0F			;*R0 = ~0X0F
    

    4、EOR异或

    EOR 目标寄存器 , 寄存器1 , 寄存器2(也可以是立即数)

    EOR R0,R0,R1			;*R0 = *R0 ^ *R1
    EOR R0,R0,#0X0F			;*R0 = *R0 ^ 0X0F
    

  • 六、跳转指令 B、BL

    1、B直接跳转

    B 跳转地址(可以是标签,因为标签就是地址)

    	MOV R0,#100			;*R0 = 100
    	B set_R1			;goto set_R1 (该操作也可以使用 LDR PC,=set_R1 理论是一样的)
    	ADD R2,R0,R1		;*R2 = *R0 + *R1 这里将不会执行,因为跳转到set_R1无法再回到当前位置
    
    set_R1:
    	MOV R1,#200
    

    2、BL暂存当前位置后直接跳转

    BL与B的不同之处就是,在跳转(给PC赋值)之前,先保存了当前的程序运行位置的地址(保存在了寄存器LR中)

    B L 跳转地址(可以是标签,因为标签就是地址)

       MOV R0,#100			;*R0 = 100
       BL set_R1			;goto set_R1 (该操作也可以使用: MOV LR,PC   SUB LR,LR,#4   LDR PC,=set_R1 理论是一样的)
       ADD R2,R0,R1		    ;*R2 = *R0 + *R1 这里将不会执行,因为跳转到set_R1无法再回到当前位置
       
    set_R1:
       MOV R1,#200
       MOV PC,LR
    

    B指令和BL指令在跳转存放的不是一个绝对地址,而存放的是一个相对地址,相对于我当前地址偏移的一个距离,存放的是一个偏移量。


  • 七、比较指令 CMP:EN、EQ、GT、LT、GE、LE

    CMP 比较寄存器1比较寄存器2(也可以是立即数)
    基础指令+模式 基础指令相关参数…

    EN 》》不等于
    EQ 》》等于
    GT 》》大于
    LT 》》小于
    GE 》》大于等于
    LE 》》小于等于

    在R0 = 10,R1 = 20的情况下

  • 允许赋值指令

    CMP R0,R1
    MOVEN ,R2,R1
    
    if(*R0 == *R1) *R2 = *R1;
    
  • 允许算数指令

    CMP R0,R1
    ADDEN ,R2,R0,R1
    
    if(*R0 == *R1) *R2 = *R0 + *R1;
    
  • 允许逻辑位指令

    CMP R0,R1
    EOREN R2,R0,R1
    
    if(*R0 == *R1) *R2 = *R0 & *R1;
    
  • 允许跳转指令

    CMP R0,R1
    BLEN  fun
    
    CMP R0,R1
    BEN  fun
    
    if(*R0 == *R1) goto fun;
    

    比较指令允许的指令不止这些,还有很多


  • 八、单个内存读写指令 LDR、STR

    1、LDR 读取内存的地址

    普通: LDR 目标寄存器 ,[读取地址]

    基地址偏移: LDR 目标寄存器 ,[读取地址纯偏移]

    基地址偏移+改变 :LDR 目标寄存器 ,[读取地址偏移并改变]!

    普通+改变 :LDR 目标寄存器 ,[读取地址], 偏移并改变

    2、STR 写入内存的地址

    普通: STR 目标寄存器 ,[读取地址]

    基地址偏移: STR 目标寄存器 ,[读取地址纯偏移]

    基地址偏移+改变 :STR 目标寄存器 ,[读取地址偏移并改变]!

    普通+改变 :STR 目标寄存器 ,[读取地址], 偏移并改变


    LDR 目标寄存器 ,[读取地址]


  • 九、多个内存读写指令 STM、LDM

    模式
    IA 先读写,后增加地址
    IB 先增加地址,后读写
    DA 先读写,后减少地址
    DB 先减少地址,后读写

    指令+模式 基地址值(必须是寄存器),{写入值}		;基地址(寄存器) 的地址不会发生改变
    指令+模式 基地址值(必须是寄存器)!,{写入值}		;基地址(寄存器) 的地址会发生改变
    
  • 1、STM

    LDM 在基地址的基础上,将数据写入偏移数据

    设R0 = 0x100,R1 = 1,R2 = 2,R3 = 3;

    以R0内存中的数值为基地址,将数据写入对应的 基地址/基地址偏移 内存中;

  • IA 先读写,后增加地址

    STMIA R0,{R1-R3}		;先写入后偏移(向高),但R0内存中的值还是0X100
    STMIA R0,{R1,R2,R3}		;编译器会将其转换成STMIA R0,{R1-R3}
    STMIA R0,{R3,R2,R1}		;编译器会将其转换成STMIA R0,{R1-R3}
    STMIA R0!,{R1-R3}		;先写入后偏移(向高),但最终R0内存中的值也会偏移变为0X110
    

  • IB 先增加地址,后读写

    STMIB R0,{R1-R3}		;先偏移后写入(向高),但R0内存中的值还是0X100
    STMIB R0,{R1,R2,R3}		;编译器会将其转换成STMIB R0,{R1-R3}
    STMIB R0,{R3,R2,R1}		;编译器会将其转换成STMIB R0,{R1-R3}
    STMIB R0!,{R1-R3}		;先偏移后写入(向高),但最终R0内存中的值也会偏移变为0X110
    

  • DA 先读写,后减少地址

    STMDA R0,{R1-R3}		;先写入后偏移(向低),但R0内存中的值还是0X100
    STMDA R0,{R1,R2,R3}		;编译器会将其转换成STMDA R0,{R1-R3}
    STMDA R0,{R3,R2,R1}		;编译器会将其转换成STMDA R0,{R1-R3}
    STMDA R0!,{R1-R3}		;先写入后偏移(向低),但最终R0内存中的值也会偏移变为0X0F4
    

  • DB 先减少地址,后读写

    STMDB R0,{R1-R3}		;先偏移后写入(向低),但R0内存中的值还是0X100
    STMDB R0,{R1,R2,R3}		;编译器会将其转换成STMDB R0,{R1-R3}
    STMDB R0,{R3,R2,R1}		;编译器会将其转换成STMDB R0,{R1-R3}
    STMDB R0!,{R1-R3}		;先偏移后写入(向低),但最终R0内存中的值也会偏移变为0X0F4
    

    2、LDM

    LDM 读取基地址内存中的数据,存放到其它地址中

    下面只举例 模式IA
    设一个R0 = 0X100,R1 = 0,R2 = 0;R1的地址为0X200,R2的地址为0X300;

    LDMIA R0,{R1,R2}

    物联沃分享整理
    物联沃-IOTWORD物联网 » 《ARM汇编编程:基础指令集入门》

    发表评论