汇编点灯练习

要求:

1、轮流将LED1、LED2、LED3及蜂鸣器点亮

2、基于STM32MP157AAA,阅读原理图和STM32MP157芯片手册

3、ARM汇编指令点灯

1、运行效果

汇编点灯

2、通过查询原理图和芯片手册,得到以下结论:

3、汇编源码

cpp 复制代码
.text 
.global _start
_start:
@R0 存放寄存器在内存中的map地址
@R1 存放寄存器的值

@1 配置RCC: LD1、LD2、LD3和蜂鸣器的使能
ldr R0, =(0x50000000+0xA28)
ldr R1, [R0]
orr R1, R1, #0x32
str R1, [R0]

@2 配置MODER寄存器
@2.1 配置LED1、LED3
ldr R0, =0x50006000
ldr R1, [R0]
bic R1, #(0x33<<16)
orr R1, #(0x11<<16)
str R1, [R0]
@2.2 配置LED2
ldr R0, =0x50007000
ldr R1, [R0]
bic R1, #(0x3<<20)
orr R1, #(0x1<<20)
str R1, [R0]
@2.3 配置蜂鸣器
ldr R0, =0x50003000
ldr R1, [R0]
bic R1, #(0x3<<12)
orr R1, #(0x1<<12)
str R1, [R0]

@3 配置OTYPER寄存器
@3.1 配置LED1、LED3
ldr R0, =(0x50006000+0x04)
ldr R1, [R0]
bic R1, #(0x5<<8)
str R1, [R0]
@3.2 配置LED2
ldr R0, =(0x50007000+0x04)
ldr R1, [R0]
bic R1, #(0x1<<10)
str R1, [R0]
@3.3 配置蜂鸣器
ldr R0, =(0x50003000+0x04)
ldr R1, [R0]
bic R1, #(0x1<<6)
str R1, [R0]

@4 配置OSPEEDR寄存器
@4.1 配置LED1、LED3
ldr R0, =(0x50006000+0x08)
ldr R1, [R0]
bic R1, #(0x33<<16)
str R1, [R0]
@4.2 配置LED2
ldr R0, =(0x50007000+0x08)
ldr R1, [R0]
bic R1, #(0x3<<20)
str R1, [R0]
@4.3 配置蜂鸣器
ldr R0, =(0x50003000+0x08)
ldr R1, [R0]
bic R1, #(0x3<<12)
str R1, [R0]

@5 配置PUPDR寄存器
@5.1 配置LED1、LED3
ldr R0, =(0x50006000+0x0C)
ldr R1, [R0]
bic R1, #(0x33<<16)
str R1, [R0]
@5.2 配置LED2
ldr R0, =(0x50007000+0x0C)
ldr R1, [R0]
bic R1, #(0x3<<20)
str R1, [R0]
@5.3 配置蜂鸣器
ldr R0, =(0x50003000+0x0C)
ldr R1, [R0]
bic R1, #(0x3<<12)
str R1, [R0]

@死循环让
loop:
	bl bee_off
	bl led1_on
	bl delay	
	bl led1_off
	bl led2_on
	bl delay
	bl led2_off
	bl led3_on
	bl delay
	bl led3_off
	bl bee_on
	bl delay
	b loop

delay:
	mov R10, #0x10000000
d2:
	sub R10, R10, #1
	cmp R10, #0
	bne d2
	mov PC, LR

led1_on:
ldr R0, =(0x50006000+0x14)
ldr R1, [R0]
orr R1, #(0x1<<10)
str R1, [R0]
mov PC, LR

led2_on:
ldr R0, =(0x50007000+0x14)
ldr R1, [R0]
orr R1, #(0x1<<10)
str R1, [R0]
mov PC, LR

led3_on:
ldr R0, =(0x50006000+0x14)
ldr R1, [R0]
orr R1, #(0x1<<8)
str R1, [R0]
mov PC, LR

bee_on:
ldr R0, =(0x50003000+0x14)
ldr R1, [R0]
orr R1, #(0x1<<6)
str R1, [R0]
mov PC, LR

led1_off:
ldr R0, =(0x50006000+0x14)
ldr R1, [R0]
bic R1, #(0x1<<10)
str R1, [R0]
mov PC, LR

led2_off:
ldr R0, =(0x50007000+0x14)
ldr R1, [R0]
bic R1, #(0x1<<10)
str R1, [R0]
mov PC, LR

led3_off:
ldr R0, =(0x50006000+0x14)
ldr R1, [R0]
bic R1, #(0x1<<8)
str R1, [R0]
mov PC, LR

bee_off:
ldr R0, =(0x50003000+0x14)
ldr R1, [R0]
bic R1, #(0x1<<6)
str R1, [R0]
mov PC, LR

.end

4、疑问

4.1 汇编代码优化

从源码中可以看出,其实有大量的重复代码,作为一名"资深"程序员,很想抽成一个一个的函数。但是实际中,这样做一定有大量的push/pop操作,而且如果程序段跨度过大,代码段的交替跳转,有可能还会影响程序执行效率(CPU会将执行代码的前后一段调入到多级缓存中,以提升执行效率)。

因此,在编写汇编的时候,应该遵循执行效率优先,还是可读性和可复用性呢?

4.2 一段反汇编代码

如图所示, =(0x50000000+0xA28)被译成了[pc, #444], 不太理解。

相关推荐
大聪明-PLUS2 小时前
Linux IIO研究(二)
linux·嵌入式·arm·smarc
大聪明-PLUS18 小时前
GPIO 也是一个接口,还有 QEMU GPIODEV 和 GUSE
linux·嵌入式·arm·smarc
Ayanami_Reii2 天前
汇编和C语言结构
c语言·汇编·笔记
大聪明-PLUS3 天前
TCP/IP 协议族—理论与实践(一)
linux·嵌入式·arm·smarc
脑子慢且灵4 天前
C语言与Java语言编译过程及文件类型
java·c语言·开发语言·汇编·编辑器
大聪明-PLUS4 天前
TCP/IP 协议族—理论与实践(二)
linux·嵌入式·arm·smarc
openHiTLS密码开源社区4 天前
ARMv9 CCA机密计算架构演进技术解析:重塑云原生时代的数据安全基石
云计算·arm·trustzone·realm·cca·机密计算·tee/ree
酷飞飞5 天前
掌握DMA基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·arm
日更嵌入式的打工仔8 天前
汇编与反汇编
汇编
大聪明-PLUS8 天前
如何从 USB 闪存驱动器安装 Debian Linux
linux·嵌入式·arm·smarc