华清远见嵌入式学习day25——ARM指令集

 .s文件中的符号
     伪操作:指导编译器对代码进行编译的
         不占用内存空间
     指令:编译器将其编译成机器码,
         存放到内存空间
     伪指令:本身不是一条指令,
         编译器在编译的时候,
         将其编译成多条指令,
         完成一条伪指令的功能
    
 汇编的基本语法
     “@” : 单行注释
     “/* */” : 多行注释
     一条指令占用一行
     汇编中不区分大小写

 汇编指令的基本格式
/*
    <opcode><code>{s}  Rd, Rn, {oprand2}
    opcode:指令的名字
    code:条件码  
        如果什么都不写代表无条件执行
    s:状态位
        指令的结果会影响cpsr的NZCV位
    Rd:目标寄存器
    Rn:第一个操作寄存器,只能是一个寄存器
        如果目标寄存器和第一个操作寄存器的编号相同
        可以合并成只写1个,类似于C语言中的双目运算符
    oprand2:第二个操作数  */
         可以是普通的寄存器
         可以是立即数或者有效数
         经过移位操作的寄存器
        
     1. 数据操作指令
     2. 跳转指令
     3. load/store指令
     4. 特殊功能寄存器操作指令
     5. 软中断
    
    
    .text    以下为代码段
    .global _start   生命一个全局的函数
_start:   函数的入口
     代码段
     1. 数据操作指令    
     搬移指令  mov  mvn
     mov/mvn<code>  Rd,  oprand2        
     mov r0, #0xFF   r0 = 0xFF  
     #号后边跟的是立即数或者有效数
     mov r1, r0    r1 = r0    
     mvn r2, r0    r2 = ~r0    
     mov r3, #0xFFFFFF
     伪指令  ldr 
     ldr r4, =0x12345678
    
     移位操作指令  lsl  lsr asr  ror 
     lsl/lsr/asr/ror<code>{s} Rd, Rn, <oprand2>
     lsl 无符号数的左移
     lsr 无符号数的右移
     asr 有符号数的右移
     ror 循环右移
     mov r0, #0xFF
     lsl r0, #0x4
     将r0中的值左移4位,赋值给R1
     高位移除,低位补0
     lsl  r1, r0, #4 
     将r0中的值右移4位,赋值给R2
     低位移除,高位补0
     lsr r2, r0, #4
     将r0中的值循环右移4位,赋值给R3
     低位移除,补到高位
     ror r3, r0, #4
    
     将r0中的值右移4位,赋值给R4
     低位移出,高位补符号位
     asr r4, r0, #4
     将r0中的值右移4位,赋值给R5
     低位移出,高位补符号位
     ldr r0, =0x800000FF
     asr r5, r0, #4
    
     mov r0, #0xFF
     mov  r1, r0, lsl #4
     mov r2, #(0xFF << 4)
    
     算数运算指令  add  adc sub sbc  mul(乘法) 
     add/adc/sub/sbc<code>{s} Rd, Rn, <oprand2>    
     假设2个64位的数相加
     第一个64位的数,
     R0存放低32位,R1存放高32位
     第二个64位的数,
     R2存放低32位,R3存放高32位
     结果R4存放低32位,R5存放高32位
.if 0        汇编中使用条件语句进行注释
     mov r0, #0xFFFFFFFF
     mov r1, #3
     mov r2, #4
     mov r3, #5    
     adds  r4, r0, r2   r4 = 0x3
     adc  r5, r1, r3   r5 = r1 + r3 + C = 0x9
.endif    
     减法指令 sub   sbc 
     两个64位数相减
     第一个64位的数,
     R0存放低32位,R1存放高32位
     第二个64位的数,
     R3存放低32位,R4存放高32位
     R4存放低[31:0]位,R5存放高[63:32]位
.if 0
    mov r0, #3
    mov r1, #9
    mov r2, #4
    mov r3, #5    
    
    subs r4, r0, r2
    sbc  r5, r1, r3    r5 = r1 - r3 - !C = 0x3
    
.endif    
     mul<code>{s} Rd, Rn, Rm
    
     mul r0, r1, r2   r0 = r1 * r2
    
     逻辑运算指令 and  orr  eor  bic
     and/orr/eor/bic<code>{s} Rd, Rn, <oprand2>
     mov r0, #0xFF
     R0[7:4]清零  --》 R1
     and r1, r0, #0xFFFFFF0F    r1 = 0xF
     and r1, r0, #(~(0xF << 4))
     R0[11:8]置一  --》 R2
     orr r2, r0, #(0xF << 8)   r2 = 0xFFF
     orr r2, r0, #0xF00
    
     R0[11:4]取反  --》 R3    r3 = 0xF0F
     eor r3, r0, #(0xFF << 4)
     eor r3, r0, #0xFF0
    
     bic 位清除指令,想把哪位清零,就给哪位写1
     R0[7:4]清零 --》r4
     bic r4, r0, #0xF0
    
     位操作指令   teq   tst  cmp 
     teq/tst/cmp<code>  Rn, oprand2
     最终影响的是cpsr的NZCV位,不需要加s
     teq 测试两个数是否相等
     mov r1, #5
     teq r1, #5
     teq r1, #6   本质:进行了异或运算
    
     tst  测试某一位是否为1
     mov r0, #0xF    0b1111
     tst r0, #0x4    0b0100
     tst r0, #0x10   0b0001 0000 本质:进行了与运算 
     tst r0, #0x18   0b0001 1000
     cmp 比较指令 
     mov r0, #4
     cmp r0, #5   本质:做减法运算
     条件码
    
     mov r0, #3
     mov r1, #4
     cmp r0, r1
     subhi r0, r0, r1
     subcc  r1, r1, r0
    
 跳转指令     b   bl  
     b/bl<code>   lable   跳转到标签下的第一条指令开始执行
     通过标签可以找到函数入口的首地址
     标签相当于C语言中函数的函数名
.if 0    
     mov r0, #3
    mov r1, #4
    b func1 
     b跳转指令,不会保存跳转指令的下一条指令的地址到lr
fo:
    add r2, r0, r1
    b loop
    
func1:
    mov r0, #5
    mov r1, #6
    add r3, r0, r1
    mov pc, #0xF     0b1100
     b fo
.endif
    
     bl 当执行bl跳转指令时,会将跳转指令的下一条指令的地址,
      保存到lr寄存器中,保存返回地址是cpu自动完成
.if 0    
    mov r0, #3
    mov r1, #4
    bl func2
    add r2, r0, r1
    b loop
func2:
    mov r3, #4
    mov r4, #5
    add r5, r3, r4
    mov pc, lr
    
    总结:跳转指令的本质:修改PC值
    子函数的调用使用bl
.endif    

.if 0
    mov r0, #9
    mov r1, #15
    
loop:
    cmp r0, r1
    beq  stop
    subhi  r0, r0, r1
    subcc  r1, r1, r0
    b loop
.endif

     特殊功能寄存器传送指令  cpsr   
     msr  cpsr, Rn    将Rn中的值赋值给cpsr
     mrs  Rn, cpsr    将cpsr中的值赋值个Rn
     如何从svc模式切换到用户模式
     M = 0x13(svc)   M= 0x10(user)
     0xD3   0b1101 0011
               IFTM MMMM
     mov r0, #0xD0
     msr cpsr, r0
     msr cpsr, #0xD0
    
    mrs r0, cpsr
    bic r0, r0, #0x1F
     and r0, r0, #(~0x1F)
    orr r0, r0, #0x10
    msr cpsr, r0
    
     作业,
     1。练习今天所有指令
     2. load/store指令
     3. 复习应用层
    
     明天下午点灯
    
     异常处理,--》按键中断


stop:    死循环相当于while(1);
    b stop
    .end 结束
    

猜你喜欢

转载自blog.csdn.net/UemTuBXuR/article/details/89359940