53.ARM彙編指令

爲什麼要學習彙編,這裏就不說了,反正就是重要。

一.常用的彙編指令

 

 

 

二.彙編指令實例

說了那麼多的指令感覺蒙圈了,其實看下例子我們就知道怎麼用了,我們完全可以將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
 

每個指令需要多練習,才能更好的去理解,在之後遇到哪個彙編指令在進行詳細的分析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章