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
 

每个指令需要多练习,才能更好的去理解,在之后遇到哪个汇编指令在进行详细的分析。

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