04 点亮LED 汇编

1 原理图

从原理图看到,3个LED分别由GPF4、GPF5和GPF6控制。

2 寄存器描述

GPF4、GPF5和GPF6可用作输入输出,或中断功能。要点亮LED,需要将IO设置为输出模式,并输出低电平。怎么做?

关于GPIO的寄存器描述如下(主要关注配置CON和数据DCT寄存器):

3个LED对应的CON与DAT寄存器功能,以及寄存器地址描述:

3 2440启动过程

大多数ARM芯片,CPU从0地址启动。

NorFlash启动时,基地址为0,片内内存地址为0x4000 0000。CPU读出Nor上第1个指令(4字节)执行,CPU继续读出其他指令执行。

NAND启动时,片内4K RAM基地址为0,NorFlash不可访问。2440硬件把NAND前4K内容复制到片内RAM,然后CPU从0地址取出指令开始执行。

CPU内部有两类寄存器:R0、R1~R15,这类寄存器可以直接访问;GPFCON、GPFDAT,这类寄存器,以地址访问。

4 ARM常用汇编

ldr指令:ldr r0, [r1]  假设r1的值为x,则读取地址x上的4字节到r0

str指令:str r0, [r1]  假设r1的值为x,则把r0的值写入到地址x

b指令:跳转

mov指令:mov r0, r1 把r1的值赋值给r0

                  mov r0, #0x100  把立即数0x100赋值给r0

ldr指令: ldr r0,=0x12345678  伪指令,最终会被拆分成几条真正的ARM指令

以下是部分ARM指令介绍:

5 点亮LED灯的汇编代码

/*
 * 点亮LED1: GPF4
 */
.text
.global _start

_start:

/* 配置GPF4为输出引脚 
 * 把0x100写到地址0x56000050(GPFCON)上
 */
	ldr r1, =0x56000050
	ldr r0, =0x100
	str r0, [r1]	/* 把r0的值写到r1的地址 */

/* 设置GPF4输出高电平 
 * 把0x00写到0x56000054(GPFDAT)上
 */
	ldr r1, =0x56000054
	ldr r0, =0x0
	str r0, [r1]	/* 把r0的值写到r1的地址 */

/*
 * 死循环
 */
halt:
	b halt

使用arm-linux-gcc进行编译,Makefile如下:

all:
	arm-linux-gcc -c -o led_on.o led_on.S	
	arm-linux-ld -Ttext 0 led_on.o -o led_on.elf
	arm-linux-objcopy -O binary -S led_on.elf led_on.bin

clean:
	rm *.bin *.o *.elf

上传到ubuntu进行编译,使用oflash烧录bin文件,可以看到点亮led。

5 ARM寄存器和汇编分析

1 修改Makefile,查看反汇编代码

all:
	arm-linux-gcc -c -o led_on.o led_on.S	
	arm-linux-ld -Ttext 0 led_on.o -o led_on.elf
	arm-linux-objcopy -O binary -S led_on.elf led_on.bin
	arm-linux-objdump -D led_on.elf > led_on.dis

clean:
	rm *.bin *.o *.elf

上述代码反汇编文件:


led_on.elf:     file format elf32-littlearm

Disassembly of section .text:

00000000 <_start>:
   0:	e59f1014 	ldr	r1, [pc, #20]	; 1c <.text+0x1c>
   4:	e3a00c01 	mov	r0, #256	; 0x100
   8:	e5810000 	str	r0, [r1]
   c:	e59f100c 	ldr	r1, [pc, #12]	; 20 <.text+0x20>
  10:	e3a00000 	mov	r0, #0	; 0x0
  14:	e5810000 	str	r0, [r1]

00000018 <halt>:
  18:	eafffffe 	b	18 <halt>
  1c:	56000050 	undefined
  20:	56000054 	undefined

下面是ARM寄存器描述:

几个重要的寄存器:

sp:stack pointer 栈指针

lr:link register  返回地址

pc:program counter  程序计数器 = 当前指令地址 + 8  (流水线架构),当前执行地址A的指令时,已经在对地址A+4的指令进行译码,已经在读取地址A+8的指令。

反汇编分析:

可以看到,这里的GPFCON、GPFDAT,在CPU看来就是内存。只不过,这些内存你写入或读出,能控制管脚。

字节序:低位保存在低地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值