为什么要学习汇编,这里就不说了,反正就是重要。
一.常用的汇编指令
二.汇编指令实例
说了那么多的指令感觉蒙圈了,其实看下例子我们就知道怎么用了,我们完全可以将C语言代码,全部使用汇编来进行实现。
示例1:
if (a==0) x=0;
if (a>0) x=x+3;
cmp r0,#0 ; R0与R1比较,做R0-R1的操作
moveq r1,#0 ; 若r0 =0,则r1=0
addgt r1,r1, #1; 若r0>0,则r1= r1 + 1
示例2:判断当前工作状态是否是ARM状态,是则切换到user 工作模式?
mrs r0,cpsr
tst r0,#0x20
andeq r0,r0,#0xFFFFFFE0 @将低五位模式位清零
orreq r0,r0,#0x10 @将低五位模式位设置成10000
msreq cpsr,r0
示例3:汇编实现下面功能
void main(void)
{
int ret=0;
func1(2);
while(1) {};
}
func1(int a)
{
if(a==2)
return func2(a);
else
return func3(a);
}
func2(int a)
{
return a+3;
}
func3(int a)
{
return a-1;
}
.text
main:
mov r5,#0
mov r0,#3
bl func1
main_end:
b main_end
func1:
mov r8,lr @备份lr寄存器中的地址
cmp r0,#2
bleq func2
blne func3
mov pc,r8
func1_end:
func2:
add r0,r0,#3
mov pc,lr
func2_end:
func3:
sub r0,r0,#1
mov pc,lr
func3_end:
.end
示例4:实现 延时1秒函数
@delay fos 1 second
delay1s:
ldr r4,=0x24f000
loop_delay1s:
sub r4,r4,#1
cmp r4,#0
bne loop_delay1s
delay1s_end:
mov pc,lr
示例5:代码段只读,数据段可读可写
.text @代码段
main:
ldr r5,=buf @伪指令
ldr r0,[r5] @load指令,将r5中的地址所对应的内容(字),放入r0中
ldrb r1,[r5] @load指令,将r5中的地址所对应的内容(字节),放入r0中
ldrh r2,[r5],#4 @load指令,将r5中的地址所对应的内容(半字),放入r0中。之后将r5中的地址向后偏移4
ldr r3,[r5],#-4 @load指令,将r5中的地址所对应的内容(字),放入r0中。之后将r5中的地址向前偏移4
ldr r6,=dest_buf1
ldr r7,=dest_buf2
ldr r8,=dest_buf3
str r0,[r6]
str r1,[r7]
strb r2,[r8]
main_end:
b main_end
.data @数据段
buf: .byte 0x01,0x02,0x03,0x04 @相当于C语言中的数组,char buf[]={0x01,0x02,0x03,0x04}
dest_buf1: .space 4 @相当于C语言中的数组,char buf[4]
dest_buf2: .space 4 @相当于C语言中的数组,char buf[4]
dest_buf3: .space 8 @相当于C语言中的数组,char buf[8]
.end @程序结束
示例6:
main()
{
int i=0;
const char buf[]={1,2,3};
char destBuf[8];
for(i=0,i<3,i++)
{
destBuf[i] = buf[i];
}
}
.text @代码段
main:
ldr r6,=buf
ldr r7,=dest_buf
mov r5,#0
loop:
cmp r5,#3
beq main_end
ldrb r0,[r6],#1
strb r0,[r7],#1
add r5,r5,#1
b loop
main_end:
b main_end
buf: .byte 1,2,3
.data @数据段
dest_buf: .space 3
.end @代码结束
示例7
实现块数据批量拷贝
r12指向源数据起始地址
r14指向源数据尾地址
r13指向目的数据起始地址
.text
ldr r12,=srcBuf
ldr r13,=dstBuf
ldmia r12!,{r0 - r11}
stmia r13!,{r0 - r11}
.data
srcBuf:
.string "abdfashuihiuhuhhiu\0"
srcBuf_end:
dstBuf:
.space 12*4
.end
示例8:堆栈操作指令
stmfd sp!,{r0-r12,lr} 将寄存器r0~r12 lr中的值存入栈中
常用于中断保护现场,! 表示会自动偏移
ldmfd sp!,{r0-r12,pc} 将栈中值逐个弹出到寄存器r0~r12 pc中
常用于中恢复断现场,表示会恢复spsr到cpsr
每个指令需要多练习,才能更好的去理解,在之后遇到哪个汇编指令在进行详细的分析。