1. 程式人生 > >s3c2440學習之路-001 彙編點亮led

s3c2440學習之路-001 彙編點亮led

1. 原理分析
2. 主要流程
3. 原始碼
4. dis檔案分析

硬體平臺:jz2440
軟體平臺:Ubuntu16.04 arm-linux-gcc-3.4.5

1.原理分析

 點亮LED最簡單的方法就是給二極體正負極接上電,中間串一個電阻

點亮Led
圖1 點亮LED

由於2440晶片Pin腳的驅動能力不夠,所以無法直接用Pin腳來點亮LED,只能把Pin腳連線到LED的負極,充當開關的作用。 
當Pin腳為高電平時,LED兩端無電壓差,LED滅
當Pin腳為低電平時,LED兩端有電壓差,LED亮

2440與LED相連
圖2 2440連線LED

2.主要流程

2.1原理圖介紹

這裡只介紹LED1, LED1負極與2440的GPF4相連,中間串聯1K電阻, LED1正極接3.3V,

在這裡插入圖片描述
圖3 LED1對應的Pin腳

在這裡插入圖片描述
圖4 LED1的接法

2.2 主要暫存器

主要使用到的暫存器只有2個
	GPFCON,控制暫存器,地址為0x56000050
	GPFDAT,資料暫存器, 地址為0x56000054

在這裡插入圖片描述
圖5 主要暫存器

2.3 軟體流程

主要流程很簡單:
	1)將GPF4配置成輸出模式
	2)將GPF4輸出低電平,即可點亮LED1

3原始碼

3.1彙編原始碼,檔名為 led_on.s

.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

3.2 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 *.elf *.o *.bin -rf

4dis檔案分析

執行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 <loop>:
  18:   eafffffe    b   18 <loop>
  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 <loop>:
地址     數值        彙編指令
  18:   eafffffe    b   18 <loop>
  1c:   56000050    undefined
  20:   56000054    undefined