ARM 练习笔记

目录

1、BIT运算 

2、LDR / STR 使用

3、比较指令 示例(CMP\TST) , 条件跳转BEQ、BNE

4、宏定义的使用

5、ADR与LDR的区别

6、CPSR寄存器控制

7、!的使用

8、DCD数组, LDR、STR示例


1、BIT运算 

  MOV     R3, #0x07
  MOV     R4, R3
  BIC     r3, r3, #0x05 ;位清除00101

  ;实现类似BIC操作
  MVN     R4, #0x05 ;R4 = ~R4 
  AND     R5, R3, R4 ; R5 = R3 & R4

2、LDR / STR 使用

  LDR R3, =NAME_ADDR ;等同于MOV R3, #0xxxxx
  LDR R4, =0x2051440
  STR R4, [SP]                 ;将R4的值保存 到 地址 SP 里(单字)
  LDR R2, [SP]                 ;将SP地址里的值 加载到R2 。 0x2051440
  STR R3, [SP, #0x04]      ;将R3的值保存到 SP + 4 的地址里

  MOV R8, SP                  ;将SP的值(地址)保存到R8
  LDR R5, [SP]                 ;将SP地址里的值 加载到R5 。 0x2051440
  LDR R6, [R8]                 ;将R8地址里的值 加载到R6 。 0x2051440
  LDR R7, [SP, #0x04]      ;将SP+4 地址里的值 加载到R7 。 #0xxxxx

--------------------------------------------

3、比较指令 示例(CMP\TST) , 条件跳转BEQ、BNE

main.c

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>

extern int asm_add(int, int);
int c_div(int a, int b){
	return a/b;
}

int main(int argc, char* argv[]){
	int a = 13;
	int b = 2;


	int result = asm_add(a, b);
	printf("hello, arm7 ! result=%d", result);
	return 0;
}

calc.S


 AREA  CALC, CODE, READONLY

  EXPORT asm_add
  IMPORT c_div


BIT_EQ PROC
 MOV R2, #0x3
 MUL R0, R0, R2
 BL BIT_OTHER
 ENDP

BIT_NE PROC
 BL c_div    ;ARMV7没有除法指令,可以自己实现,或者调用C/C++的
 BL BIT_OTHER
 ENDP

asm_add PROC
  ;LDR R2, [R0, #0x4]
  NEG R0, R0
  CMP R0, #-0x3
  BEQ ADD_NUM
  BNE SUB_NUM
NUM_OTHER
  MOV R2, #0x5
  TST R2, #0x2 ;判断是否设置了标志为010
  STR LR, [SP] ;将LR保存到SP。后面的跳转用的BL,而不是B,会覆盖LR
  BNE BIT_EQ   ;设置了标志位010,运算结果为1,则Z=0
  BEQ BIT_NE   ;没有设置标志位010,运算结果为0,则Z=1
BIT_OTHER
  LDR LR, [SP] ;从SP里读取出原先的LR,还原 函数跳转地址
  BX      LR
ADD_NUM
  ADD R0, R1
  B NUM_OTHER
SUB_NUM
  SUB R0, R1
  B NUM_OTHER
  ENDP

  END

--------------------------------------------

4、宏定义的使用

 AREA  CALC, CODE, READONLY

  EXPORT asm_add

  MACRO                                     ; 声明宏定义
  MacSum $RD ; 定义宏名,参数
  MOV v8, #0
LOOP
  ADD v8, $RD, v8                       ;
  SUBS $RD, $RD, #1
  BNE LOOP
  MOV $RD, v8
  MEND

  MACRO
  SUB_SHI $Rd, $Rn
  SUB $Rd, $Rn
  MEND

asm_add PROC
  MacSum R0
  SUB_SHI R0, #0x10
  BX      LR
  ENDP

  END

--------------------------------------------

5、ADR与LDR的区别

asm_add PROC
  LDR R1, =0x01    ;将地址0x01保存到 R1
  LDR R2, CMN_EQ   ;将CMN_EQ 的地址指向的字 保存到R2
  ADR R3, CMN_EQ   ;将CMN_EQ 的地址保存到R3
  LDR R4, =CMN_EQ  ;将CMN_EQ 的地址保存到R4
  NOP
OTHER
  BX      LR
CMN_EQ
  MOV R0, #0x2
  B OTHER
  ENDP

  END

结果:

--------------------------------------------

6、CPSR寄存器控制

 MRS R4, CPSR 
 BIC R4, R4, #0x80
 MRS R5, CPSR
 --------------------------------------------

7、!的使用

已经R0=13,R1 = 2,下面 R3、R4、R5值分别是多少?

 MOV R2, SP
 STR R0, [R2], #0x4  ;将R0存入R2,然后R2 地址 + 0x4
 LDR R3, [R2, #-0x4]! ;从R2-0x4 地址里取出字 存入R3,R3=13。 !的意思就是 地址更新,结果写回到Rn中,Rn不允许是R15。这里等于R2 = R2-0x4
 LDR R4, [R2]            ;R4 = 13
 STR R1, [R2]            ;将R1 存入 R2的地址里(将原先的13覆盖了)
 LDR R5, [R2]            ;取出R2地址里的 字存入R5,R5 = 2

 --------------------------------------------

8、DCD数组, LDR、STR示例

clac.S

 PRESERVE8
 AREA CLAC, CODE, READONLY
 EXPORT asm_add

Array DCD 0x11, 0x22, 0x33, 0x44
 DCD 0x55, 0x66, 0x77, 0x88
 DCD 0x00, 0x00, 0x00, 0x00

asm_add PROC
 STMFD SP!, {LR}

 LDR R0, = Array
 LDR R2, [R0]
 MOV R1, #4
 LDR R3, [R0, R1, LSL #2]
 ADD R2, R2, R3
 MOV R1, #8
 STR R2, [R0, R1, LSL #2]
 ;BX LR
 LDMFD SP!, {R1}
 MOV PC, R1
 ENDP

 END

结果:

不懂 LDR R3, [R0, R1, LSL #2] 什么意思?看这里 https://www.heyrick.co.uk/armwiki/LDR

 --------------------------------------------

8、a>b? 1: 2 如何实现

 PRESERVE8
 AREA CLAC, CODE, READONLY
 EXPORT asm_add

getMax
 CMP R0, R1
 MOVHI R0, R0
 MOVLS R0, R1
 BX LR

NUM_1 EQU 19
NUM_2 EQU 20

asm_add PROC
 STMFD SP!, {LR}

 MOV R0, #NUM_1
 ;MOV R1, NUM_2
 LDR R1, =NUM_2
 BL getMax

 ;BX LR
 LDMFD SP!, {PC}
 ENDP

 END
发布了106 篇原创文章 · 获赞 204 · 访问量 128万+

猜你喜欢

转载自blog.csdn.net/ab6326795/article/details/90287593