ARM 裸机开发 day02 学习笔记

一、基础指令

1.mov

MOV{S}<c> <Rd>, #<const>

MOV{S}<c> <Rd>, <Rm>

s:是否影响CPSR状态寄存器;Rd目标寄存器;Rm源寄存器

mov r0, #1 ; r0 = 1

mov r1, #2 ; r1 = 2

mov r2, r1 ; r2 = r1

mov r3, r1, lsl #2 ; r3 = r1 << 2

mov r4, r0, lsl #1 ; r4 = r0 << 1

=>移位指令

LSR 逻辑右移:最高位补0,无符号数

ASR 算术右移:最高位补符号位,有符号数

ROR 循环右移:最低位移出来,放到最高位

LSL 逻辑左移:低位补0

=>立即数

  1. 数值在 0 ~ 0xFF,直接是合法立即数

  2. 展开二进制,最高位1到最低位1之间,二进制位数不能超过8位

  3. 8位二进制数,向右移动偶数次得到该数

2. add sub

add

加法

ADD{S}{<C>} <Rd>, <Rn>, #<const>

ADD{S}{<C>} <Rd>, <Rn>, <Rm>{,<shift>}

mov r1, #2

add r0, r1, #3 ; r0 = r1 +3 = 5

add r2, r0, r1 ; r2 = r0 + r1 =7

add r3, r1, r2, lsl #4 ; r3 = r1 + (r2 <<4)

sub

减法

SUB{S}{<C>} <Rd>, <Rn>, #<const>

SUB{S}{<C>} <Rd>, <Rn>, <Rm>{,<shift>}

mov r0, #5

mov r1, #3

sub r2, r0, #1 ; r2 = r0 -1 = 4

sub r2, r0, r1 ; r2 = r0 - r1 = 2

sub r3, r0, r1, lsl #4 ; r3 = r0 - (r1 <<4)

3. ldr str

ldr

Load,从内存加载数据到通用寄存器

LDR{<C>}{<Q>} <Rt>, <label>

LDR{<C>} <Rt>, \{,#+/-\}

ldr r0, =0x40000000 ; 将立即数加载到通用寄存器

ldr r1, r0 ; r1 = *r0,把r0指向内存的数据读到r1

str

Store,把寄存器数据写入内存RAM

str r1, r0 ; *r0 = r1

str r1, r0, #4 ; *(r0+4) = r1

str r1, r0, #4 ; *(r0) = r1,然后 r0 = r0 + 4(后变址)

str r1, r0, #4! ; r0 = r0 + 4,然后 *r0 = r1(前变址,!代表更新基址寄存器)

=>两数求和

ldr r0, =0x40000000 ; 变量i地址

ldr r1, r0 ; r1 = *r0

ldr r0, =0x40000004 ; 变量j地址

ldr r2, r0 ; r2 = *r0

add r3, r1, r2 ; r3 = r1 + r2

ldr r0, =0x40000008 ; sum地址

str r3, r0 ; *r0 = r3

4. BIC ORR

BIC

位清零。将寄存器某些bit清0,结果放回寄存器

BIC{S}{<C>} <Rd>, <Rn>, #<const>

ORR

位置1。将寄存器某些bit置1,结果放回寄存器

ORR{S}{<C>} <Rd>, <Rn>, #<const>

5.b

①判断

比较三个数,找出最大值

cpp 复制代码
    mov r1, #1
    mov r2, #5
    mov r3, #7

    cmp r1, r2
    bgt great
    blt less

great
    mov r0, r1
    b label

less
    mov r0, r2
    b label

label
    cmp r0, r3
    bgt finished
    movlt r0, r3

finished
    b finished

②循环

求1+2+...+100

a.do while 循环

先执行,后判断(至少执行一次)

cpp 复制代码
    mov r0, #1 ; i
    mov r1, #0 ; sum

loop
    add r1, r0, r1 ; sum = sum + i
    add r0, r0, #1 ; i++
    cmp r0, #100
    ble loop ; i<=100 

finished
    b finished

b.while循环

先判断,后执行

cpp 复制代码
    mov r0, #1
    mov r1, #0

loop
    cmp r0, #100
    bgt finished ; i>100
    add r1, r0, r1
    add r0, r0, #1
    b loop

finished
    b finished

③ bl bx lr

• bl label:跳转,自动把返回地址保存到lr(r14)

• bx lr:等价于 mov pc, lr,返回调用处

cpp 复制代码
start
    mov r0, #10
    mov r1, #15
    bl max_of_two_numbers       ;调用函数

max_of_two_numbers
    cmp r0, r1
    movge r2, r0
    movlt r2, r1
    bx lr                       ;返回调用处,继续执行下一条指令

6.STMFD / LDMFD

栈4种实现:

空增:先写数据,指针自增

空减:先写数据,指针自减

满增:指针自增,再写数据

满减:指针自减,再写数据(ARM默认)

a.STMFD

入栈,保存现场

STMFD{<C>} <Rn>{!}, <registers>

!:执行完指令自动更新Rn(sp)

stmfd sp!, {r0, r1, r2, r3-r12, lr}

b.LDMFD

出栈,恢复现场

ldmfd sp!, {r0, r1, r2, r3-r12, lr}

7.调用

1) 汇编调用C函数

a.参数≤4个

用r0~r3传递参数;返回值放在r0

cpp 复制代码
    import add_c
    stmfd sp!, {r0-r12, lr}
    mov r0, #1
    mov r1, #2
    mov r2, #3
    mov r3, #4
    bl add_c           ;调用C函数
    ldmfd sp!, {r0-r12, lr}
    bx lr

b.参数>4个

从第5个开始,压栈传递

cpp 复制代码
    import add_c
    stmfd sp!, {r0-r12, lr}
    mov r0, #1
    mov r1, #2
    mov r2, #3
    mov r3, #4
    mov r4, #5
    push {r4} ;第5个参数压栈
    bl add_c
    pop {r4}
    ldmfd sp!, {r0-r12, lr}
    bx lr

2)C语言调用汇编函数

汇编文件中用export导出函数

C文件中用extern声明

汇编函数内部要负责现场保护与恢复

cpp 复制代码
    export asm_func
asm_func
    add r2, r2, #100
    bx lr

8.MRS MSR

处理器工作模式切换

MRS

读特殊寄存器(CPSR)到通用寄存器

MRS{<C>} <Rd>, <spec_reg>

MSR

把通用寄存器的值写入特殊寄存器(CPSR)

MSR{<C>} <spec_reg>, <Rd>

切换到USER模式:

cpp 复制代码
    mrs r0, cpsr      ;把cpsr读到r0
    bic r0, r0, #0x1F ;清除模式位
    orr r0, r0, #0x10 ;设置USER模式编码
    msr cpsr_c, r0    ;写回cpsr
相关推荐
_upupup1 小时前
Linux的调试工具——gdb/cgdb
linux·服务器
JeJe同学2 小时前
Docker镜像导入、容器启动
linux·运维·docker
Jason_zhao_MR2 小时前
Linux与实时控制如何兼得
linux·嵌入式硬件·机器人·工业控制
闲云野鹤在人间3 小时前
MySQL|从理论、安装、备份到主从复制、MHA高可用详解
linux·运维·数据库·mysql·云计算
一个风轻云淡4 小时前
GCC 和 GDB命令简单解读
java·linux·前端
H.莓飛4 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
资料库014 小时前
Linux 8个常见运维故障排查
java·linux·运维
零基础1235 小时前
Ubuntu 常用命令汇总
linux·运维·开发语言
Android系统攻城狮5 小时前
Linux Gstreamer深度解析之gst_audio_sink_get_type调用流程与实战(六十五)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
xiaoqiMikko5 小时前
Linux 实战(一):CentOS 7、Rocky 9、Ubuntu 24.04 三台真机实测 —— 认清系统、换源、装包的版本坑
linux·centos