您尚未登录。

楼主 #1 2018-05-02 10:25:22

xinxiaoci
会员
注册时间: 2018-04-18
已发帖子: 71
积分: 71

点亮LED——汇编

《单片机小白转嵌入式Linux学习记录,基于S3C2440----目录》

---------------------------------------
GPIO
General Purpose intput output  通用输入输出

---------------------------------------


网络标号:nLED_1
点亮条件:低电平点亮
对应IO:GPF4

准备知识:

S3C2440A芯片手册
    9.I/O Ports
        PORT F CONTROL REGISTERS 292页
        GPFCON 0x56000050   //GPIO F 的配置寄存器 配置输入/输出/外部中断
        GPFDAT 0x56000054   //GPIO F 数据寄存器 控制电平的高低
       
       
       
-----------------------------------------       
cpu启动过程

Nor 启动

Nor Flash 基地址为0地址,cpu片内4K RAM基地址为0x4000 0000。
CPU从Nor Flash上读取第一条指令。


Nand Flash 启动

片内4K RAM 基地址为地址线上的0地址,Nor Flash 不可用。
Nand控制器把Nand Flash 前4K 数据复制到片内4K RAM ,然后CPU从片内4K RAM 执行第一条命令。

CPU都是0地址开始执行。

-----------------------------------------
一些简单的ARM 汇编
1.LDR   load 读内存,32位 4字节

LDR R0,[R1]     ;设R1的值为0x000000EF 读取 0x000000EF 地址上的数据 4字节 保存到R0中

2.STR     store 写内存指令

STR R0,[R1]     ;设R1的值为0x000000EF 将R0寄存器的值写到 0x000000EF 地址指向的内存中。

3.B     break 跳转

4.mov   move 移动

mov R0,#0x100   ;R0 = 0x100 0x100 是立即数一条机器码能放下

mov R0,#0x12345678  ;这是一条错误指令,一条ARM指令是32位,0x12345678已经占用了32位,一条机器码放不下这条指令,以后遇到再说

5.伪指令
LDR R0,=#0x12345678 ;可以放置任意数 而 mov R0,#0x100 只能处理立即数

----------------------------------------
代码文件:led_on.S

.text
.global _start

_start:
   
    /* 配置GPF4为输出模式 */
    ldr r1,=0x56000050     
   
    ldr r0,=0x100           /* mov r0,#0x100 */
    str r0,[R1]
   
    /* GPF4为输出低,点亮led */
    ldr r1,=0x56000054
    ldr r0,=0               /* mov r0,#0 */
    str r0,[R1]
   
    /* 死循环 */
halt:
    b halt
------------------------------------------   

gcc 编译

1.命令行
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    //翻译成汇编
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 *.bin *.o *.elf
   
    然后执行
        make 或 make clean
-----------------------------------------
led_on.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 <halt>:
  18:   eafffffe    b   18 <halt>
  1c:   56000050    undefined
  20:   56000054    undefined
 
-----------------------------------------



扩展知识:
   
MOV立即数:
立即数保存在32位机器码的后12位,在这12位数中,设低8位为immed_8,高4位为rotate,那么 立即数=immed_8循环右移(2*rotate)位 如0x100 在机器码后12位的表示为 1100 0000 0001  如:上面反汇编的内存4 机器码为 e3a00c01 后12位 c01即为立即数0x100在机器码中的表示

流水线:
当前执行地址A的指令时,已经对A+4地址指令进行了译码,已经在读取地址A+8的指令,所以 PC = A+8 (PC:Program counter 程序计数器)
如:上面反汇编 内存0  ldr r1, [pc, #20]  r1=[0+8+20]=[0x1c] 将0x1c内存中的数值0x56000050 传递给r1

寄存器对于CPU来说,也是内存,与普通内存没什么区别。

寄存器别名对应关系:
R1      a1
R2      a2
R3      a3
R4      a4
R5      v1
r6      v2
r7      v3
r8      v4
r9      v5
r10     v6
r11     fp
r12     ip
r13     sp      stack pointer       栈指针
r14     lr      link register       返回地址
r15     pc      program counter     程序计数器

led.jpeg

最近编辑记录 xinxiaoci (2018-05-03 18:51:22)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn