爲什麼要學習彙編,這裏就不說了,反正就是重要。
一.常用的彙編指令
二.彙編指令實例
說了那麼多的指令感覺蒙圈了,其實看下例子我們就知道怎麼用了,我們完全可以將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
每個指令需要多練習,才能更好的去理解,在之後遇到哪個彙編指令在進行詳細的分析。