ARM_Linux_NOTE_2

ARM_Linux NOTE_2

Vine Farer
2016.08.09

1、ARM裸板汇编

1)立即数

一条指令是32位,最后一个操作数只剩下12位,高四位放幂,后8位放有效位

  • 当一个数的有效位(第1个1到最后一个1 总间隔)小于8位( 256 ),则是立即数
  • 当一个数的有效位大于8位,则不是立即数
  • 当一个数的有效位等于8:

    1)最后一个1在奇数位上,不是立即数

    2)最后一个1在偶数位上,是立即数

  • 若一个数按位取反是立即数,称之为有效数,只能用于mov后面。

    如:mov r0,#0xff00ffff
    其反汇编生成 mvn r0, #0x00ff0000



2)相关指令

  • 数据处理指令

    算数指令:ADD、ADC、SUB、SBC、RSB、RSC

    逻辑指令:BIC、AND、ORR、EOR

    比较指令:CMP、CMN、TST、TEQ

    数据搬移:MOV、MVN
    (mov用来访问CPU内部寄存器,str、ldr用来访问片外资源,如内存或片上外设寄存器)

    此类指令只能对寄存器操作,不针对存储器

    • 进位加法

      ADDS r0, r0, r1 //加S是因为要让这个操作影响CPSR标志位(进位c)

      ADC r2,r2,r3//ADC是带进位的加法,如果上一条指令产生进位则一起加进来

    • 借位减法

      SUBS r0, r0, r1 //加S是因为要让这个操作影响CPSR标志位(进位c)

      SBC r2, r2, r3// SBC 是带进位的减法指令

  • SWP

    功能:寄存器和存储器间,由一次存储器读、一次存储器写组成原子操作。完成一个字节或字的交换

    不会被中断异常打断

    可以用来实现信号量

  • 软中断SWI

    32位:4位条件码、4位指令码、24位数据(包括 SWI 号)

    产生异常陷阱,跳转到SWI硬件向量

    SWI处理程序课检测SWI号,再采取对应操作
    ldr r0,[lr,#-4]
    bic r0,r0,#0xff000000

    进入 SVC 模式,进行特权操作

  • PSR传送指令

    专门用来访问 CPSR

    MRS 读取 CPSR 值,改变后,由 MSR 写回 CPSR



3)ARM处理器寻址方式

  • 立即数:有一个数据是通过立即数获得

    mov r0,#34
    add r0,r1,#56

  • 寄存器寻址:所有操作数都是通过寄存器直接获得

    mov r0,r1
    add r0,r1,r2
    sub r0,r1,r4

  • 寄存器移位寻址:有一个操作数是通过寄存器移位计算获得

    mov r0,r1,lsl #4
    add r0,r1,r2,lsl #12

  • 寄存器间接寻址:把一个寄存器的值当做指针,来读写内存值

    ldr r0,[ r1 ] <=> r0 = *( r1 )
    str r0,[ r1 ] <=> *( r1 ) = r0
    (*往往会同时用到伪指令:ldr r0, = 0xffff0000. 让r0存一个值或地址 )

    ldrb strb ldrsb
    ldrh strh ldrsh

  • 基址变址寻址:把一个寄存器值当做基地址,然后做地址偏移,访问内存

    前索引:ldr r0,[ r1,#4 ] a = *( p + 1 )

    后索引:ldr r0,[ r1 ],#4 a = *( p ++ )

    自动索引: ldr r0,[ r1,#4 ]! a = *( ++p )

  • 多寄存器寻址:一次赋值或拷贝多个寄存器

    ldmxx r0!,{r1-r6,r9}
    stmxx r0!,{r1-r6,r9}

    i:增,指针增加 a:后,先取值后累加
    d:减,指针减小 b:前,先累加后取值

  • 堆栈寻址:专项用于 堆栈的 多寄存器寻址

    ldm、stm

    f:满、a:增、e:空、d:减

    ldmfd sp!,{r0-r12,lr} pop
    stmfd sp!,{r0-r12,lr} push

  • 相对寻址:相对于当前pc值得跳转

    b、bl
    bx、blx 带指令集切换跳转



2、ARM汇编代码

LED实验

  • 通过查找芯片手册与原理图找到需要配置的管脚
  • 配置相应管脚的寄存器
  • 源码(程序单步运行验证结果)

    安全代码:不影响其他寄存器中原有状态,只改变待操作的寄存器状态

    .text
    .globl _start
    _start:
    
        ldr r0,=0x114001e0   #读取GPF3CON寄存器地址到r0
        ldr r1,[r0]          #让r1存放r0指向的地址内的值,即待配置的寄存器值
        bic r1,r1,#0xf00000  #清零相应位
        orr r1,r1,#0x100000  #相应位置一
        str r1,[r0]          #将修改后的r1内的值回写到对应寄存器中
                             #管脚呈输出态
    
        ldr r0,=0x114001e4   
        ldr r1,[r0]
        orr r1,r1,#0b100000  #将对应数据寄存器置1,管脚输出高电平
        str r1,[r0]          #灯亮
    
        ldr r0,=0x114001e4
        ldr r1,[r0]
        bic r1,r1,#0b100000  #将对应数据寄存器清0,管脚输出低电平
        str r1,[r0]          #灯灭
    
    _stop:
        b _stop

    不安全代码:直接赋值给寄存器,会改变其他位的状态,不推荐

    ldr r1,=0x114001e0
    ldr r0,=0x00110000  #改变两个引脚状态为输出态
    str r0,[r1]
    
    ldr r1,=0x114001e4
    ldr r0,=0x30        #直接让led5、led4亮
    str r0,[r1]
  • Makefile
    SHELL=C:\WINDOWS\system32\cmd.exe
    all:
        arm-none-eabi-gcc -c -g asm.s -o asm.o
        arm-none-eabi-ld  -Ttext 0x40008000 asm.o -o asm.elf
        arm-none-eabi-objdump -D asm.elf > asm.dis  #生成反汇编文件
    clean:
        rm -rf *.elf *.o



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值