汇编点灯练习

要求:

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], 不太理解。

相关推荐
188号安全攻城狮1 天前
【PWN】HappyNewYearCTF_9_ret2syscall
linux·汇编·安全·网络安全·系统安全
万法若空1 天前
Vim常用指令汇编
汇编·编辑器·vim
uoscn2 天前
从零开始实现U-Boot
arm·imx6ull·u-boot
请输入蚊子2 天前
«操作系统真像还原» 第二章 编写MBR主引导记录
linux·汇编·操作系统·bochs·操作系统真像还原
188号安全攻城狮2 天前
【PWN】HappyNewYearCTF_8_ret2csu
linux·汇编·安全·网络安全·系统安全
小郭团队3 天前
2_6_五段式SVPWM(经典算法+DPWM2)算法理论与MATLAB实现详解
算法·matlab·硬件架构·arm·dsp开发
CQ_YM4 天前
ARM之lcd与pwm
arm开发·单片机·嵌入式硬件·arm
梁洪飞4 天前
解决摄像头驱动起不来的情况
linux·arm开发·图像处理·嵌入式硬件·arm
暮云星影5 天前
四、linux系统 应用开发:UI开发环境配置概述 (三)
linux·ui·arm
切糕师学AI5 天前
ARM 汇编指令系列文章导读
汇编·arm开发