目录
3、比较指令 示例(CMP\TST) , 条件跳转BEQ、BNE
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