1. 原理分析
2. 主要流程
3. 源码
4. dis文件分析
硬件平台:jz2440
软件平台:Ubuntu16.04 arm-linux-gcc-3.4.5
点亮LED最简单的方法就是给二极管正负极接上电,中间串一个电阻
由于2440芯片Pin脚的驱动能力不够,所以无法直接用Pin脚来点亮LED,只能把Pin脚连接到LED的负极,充当开关的作用。
当Pin脚为高电平时,LED两端无电压差,LED灭
当Pin脚为低电平时,LED两端有电压差,LED亮
这里只介绍LED1, LED1负极与2440的GPF4相连,中间串联1K电阻, LED1正极接3.3V,
主要使用到的寄存器只有2个
GPFCON,控制寄存器,地址为0x56000050
GPFDAT,数据寄存器, 地址为0x56000054
主要流程很简单:
1)将GPF4配置成输出模式
2)将GPF4输出低电平,即可点亮LED1
.text
.global _start
_start:
/* 1, set output mode
* GPFCON [9:8] 01
* 0x56000050
*/
ldr r1, =0x56000050
ldr r0, =0x100
str r0, [r1]
/* 2, set value to 0
* GPFDAT [4] 0
* 0x56000054
*/
ldr r1, =0x56000054
ldr r0, =0
str r0, [r1]
loop:
b loop
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 *.elf *.o *.bin -rf
执行Makefile后,会生产led_on.elf文件。再通过 arm-linux-objdump -D led_on.elf > led_on.dis 生成dis文件
产生的dis文件内容如下
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 :
18: eafffffe b 18
1c: 56000050 undefined
20: 56000054 undefined
因为ARM是流水线处理,分三步:取指,译码,执行。当执行到某条命令时,PC的数值已经跳到了当前命令地址+8的位置。
下面是对dis文件的分析
分析反汇编代码
led_on.elf: file format elf32-littlearm
Disassembly of section .text:
地址 机器码 汇编指令
00000000 <_start>:
这里是pc+20的值, pc = 当前地址+8 = 0 + 8
[pc, #20] = [0 + 8 + 20] = 28 = 0x1c
0x1c 地址的数值是 56000050
r1 = 56000050
0: e59f1014 ldr r1, [pc, #20] ; 1c <.text+0x1c>
r0 = 0x100
4: e3a00c01 mov r0, #256 ; 0x100
56000050 地址的值 = 0x100
8: e5810000 str r0, [r1]
[pc, #12] = [ 0xc + 8 + 12] = 32 = 0x20
0x20 地址的数值是56000054
r1 = 56000054
c: e59f100c ldr r1, [pc, #12] ; 20 <.text+0x20>
r0 = 0
10: e3a00000 mov r0, #0 ; 0x0
56000064地址的值=0
14: e5810000 str r0, [r1]
00000018 :
地址 数值 汇编指令
18: eafffffe b 18
1c: 56000050 undefined
20: 56000054 undefined