《嵌入式硬件(六):ARM汇编核心内容总结》

一、ARM汇编指令

1.move

move{s}<c> <rd>, <rm>

2.add

1)add{s}<c><rd>, <rn>,#<const>

cs 复制代码
add r0, r1, #1

2)add{s}<c><rd>, <rn>, <rm> {,<shift>}

cs 复制代码
add r0, r1, r2

3)add{s}<c><rd>, <rn>, <rm> , <type> <rs>

cs 复制代码
add r0, r0, r1, lsl, r1

3.sub

1)sub{s}<c><rd>, <rn>,#<const>

cs 复制代码
sub r0, r1, #1

2)sub{s}<c><rd>, <rn>, <rm> {,<shift>}

cs 复制代码
sub r0, r1, r2

3)sub{s}<c><rd>, <rn>, <rm> , <type> <rs>

cs 复制代码
sub r0, r0, r1, lsl, r1

tips:立即数(immediate)

定义:指令中可以直接包含的常数

1)数值范围在0~0xFF之间,这个数一定是立即数

2)把数展开为二进制数,最高位及最低位之间的位数不能超过8

3)把数展开位二进制数,右边0的个数,必须是偶数

|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 |

在arm中存取数据,一个数占12个比特,但是arm为了让存的数字更大,将前四位设置为旋转位,现在后八位是0xFA,如果要存0xFA00,就要将当前的数字循环右移24次,旋转位填循环次数的1/2。

当不是立即数时,但是又用到mov,此时编译器会自动调用mvn,mvn的存取方式是先对操作数按位取反再进行存取

4.ldr

ldr的作用是从ram或指定的地址加载数据到通用寄存器中

ldr<c><rt>, \{,#+/-\}

cs 复制代码
ldr r1, [r0]

这行代码的作用是将r0寄存器的内容放到r1

tips:ram对内存的划分

|--------------|
| 0xFFFFFFFF-1 |
| |
| 0x40001000 |
| 0x40000FFF |
| |
| 0x40000000 |
| |
| 0x20000 |
| 0x1FFFF |
| |
| 0x00000000 |

0x00000000~0x1FFFF:代码区(nor flash)

0x40000000~0x40000FFF:片上RAM(变量存放)

其他空白空间:外设寄存器

5.str

str的作用是把通用寄存器中的数据加载到ram或指定的地址

cs 复制代码
str r1, [r0]

这行代码的作用是将r1的内容写到r0中

6.bic

作用:指定位清零

bic{s}<c> <rd>, <rn>, #<const>

7.orr

作用:指定位置一

orr{s}<c> <rd>, <rn>, #<const>

8.跳转

b:跳转到标识符,不改变链接寄存器

bl:跳转到标识符,改变链接寄存器

bx:后面跟寄存器地址,作用是将这个地址装入pc

9.stmfd

入栈,保护现场

stmd<c> <rn> {!}, <registers>

加上感叹号表示sp栈指针可变,registers表示用列表的形式写要保存的寄存器地址

10.ldmfd

出栈,恢复现场

ldmd<c> <rn> {!}, <registers>

加上感叹号表示sp栈指针可变,registers表示用列表的形式写要保存的寄存器地址

11.mrs

读取某个特殊寄存器

mrs<c> <rd>, <spec_reg>

12.msr

读取通用寄存器

msr<c> <spec_reg>, <rd>

二、汇编模拟

1.cpsr

|----------------------|---------|-------------------|-------------------------------------|
| n | z | c | v |
| 有符号时,结果为负的情况 下置一,正置零 | 结果为零,置一 | 无符号的情况下 进位置一,借位置零 | 有符号的情况下,俩个最高位位0的数相加结果为1,最高位为1相加0,置一 |

作用:可以根据这四位实现c语言中if else的作用

加上后缀就可以实现

三、函数调用

tips:栈

空栈:入栈时,先入栈再挪

满栈:入栈时,先挪再入栈

增栈:入栈地址由低到高

减栈:入栈地址由高到低

在keil中,

汇编调c

1)保护现场

2)import声明

3)用r0~r3或者栈来传参

4)bl跳转

5)恢复现场

c调汇编

1)用extern声明

2)函数调用(在keil下,需要在汇编里加export 函数名,来声明函数)

3)靠r0把结果返回c,需要在汇编里面把结果写入r0

谁调用,谁保护恢复现场

四、代码

cs 复制代码
ldr pc, =_start

_asm_max
	mov r0, #0
	mov r1, #1
	stmfd sp!, {r0-r12, lr}
	bl _asm_min
	ldmfd sp!, {r0-r12, lr}
	cmp r0, r1
	movge r2, r0
	movge r2, r1
	bx lr

_asm_min
	cmp r0, r1
	movge r2, r1
	movge r2, r0
	mov r0, r2
	bx lr

_start
	ldr sp, =0x40001000
//调用汇编
	;stmfd sp!, {r0-r12, lr}
	;bl _asm_max
	;ldmfd sp!, {r0-r12, lr}
//调用c程序
	import c_max	
	mov r0, #1
	mov r1, #2
	bl c_max

    ldr sp, =0x40001000
    sub sp, sp, #1024


finished
	b finished
	end

sp需要布局,因为每个模式都有自己独立的sp

相关推荐
智闲电子设计3 小时前
STM32 SD 卡 + FatFS 实战:掉电丢数据?f_sync 和簇对齐写救你
stm32·单片机·嵌入式硬件
ヾChen4 小时前
ESP32 OTA 踩坑实录
stm32·单片机·嵌入式硬件·物联网·学习
DevHub5 小时前
probe-rs 教程:一行命令替代 OpenOCD 烧写调试 Cortex-M
arm开发·嵌入式硬件·mcu·rust
小僧景贤5 小时前
嵌入式ADC高阶深度解析:基于STM32底层原理、误差溯源、硬件调校与工业级落地
单片机·嵌入式硬件·stm32 adc·工业级高精度采集·adc 误差校准·量产固件开发
黑猫学长呀5 小时前
【驱动开发常见问题】编译出现rm: cannot remove `asm/arch‘: Is a directory
驱动开发·单片机·嵌入式硬件·bug·编译报错·kernrl
Be for thing8 小时前
【嵌入式成长10】STC89C51蜂鸣器|有源/无源蜂鸣器区分、三极管驱动、定时器播放音乐实战
单片机·嵌入式硬件·学习
郎哥编程课堂8 小时前
单片机零基础训练营第2天:嵌入式开发常用的三种进制
单片机·嵌入式硬件
LCG元8 小时前
STM32 DAC+DMA+定时器触发生成任意波形:数据对齐陷阱、输出缓冲器选型与频率精度实测
stm32·单片机·嵌入式硬件
etc95279 小时前
IAR下如何同时指定section的LMA和VMA
arm开发·嵌入式硬件·mcu
LuminousCPP10 小时前
嵌入式-51单片机入门(三)-数码管驱动:从单管点亮、多位扫描到动态刷新与消隐原理
笔记·单片机·嵌入式硬件·51单片机