(嵌入式)关于arm中的存储控制器(三)终!
来源:互联网 发布:照片图库 mac 密码 编辑:程序博客网 时间:2024/06/06 00:48
.equ:
.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression),该指令并不分配空间,相当于C语言中的#define宏定义。
LR寄存器:
LR(link register)连接寄存器,在ARM体系结构中LR的特殊用途有两种:
1.用来保存子程序的返回地址。
2.当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的位置继续执行。
当通过BL或者BLX指令调用子程序时,硬件自动将子程序返回地址保存在R14(LR)寄存器中,在子程序返回时,把LR的值赋值到程序计数器PC即可实现子程序返回(eg:MOV PC,LR)。
ADR指令:
这是一条小范围的地址读取伪指令,它将基于PC的相对偏移地址值读到目标寄存器中。
使用格式: ADR register,exper
在编译源程序时,编译器首先计算出当前PC到exper的偏移值#offset_to_exper,然后使用一条ADD或者SUB指令来替换这些伪指令,例如,ADD resister,PC,#offset_to_exper
注意标号exper与指令必须在统一代码段。
ADRL指令:
这是一条中等范围的地址读取伪指令,它将基于PC的相对偏移地址值读到目标寄存器中。
原理和ADR一样,不同的是它在编译的时候,会被用两条合适的指令来替换伪指令。
eg:ADD register,PC,offset1
ADD register,register,offset2
所以上面adrl r2, mem_cfg_val 意思是把下面那13个值的起始存储地址存入到r2寄存器。
.long:
定义一个4字节数据,并为它分配空间
.align n:
它的作用是对指令或者数据存放的地址按 2^n 进行对齐。下面是指定按 2^4 对齐。
c语言main函数:
Makefile:
-m 后面跟的cpu架构,arm就表示arm架构的cpu
> 表示将这个程序的反汇编文件西写入到led1.dis这个文件中,在终端中不显示出来
如果不加这个> ,那么你在终端上就可以看到输出的LED1_elf反汇编程序
.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression),该指令并不分配空间,相当于C语言中的#define宏定义。
LR寄存器:
LR(link register)连接寄存器,在ARM体系结构中LR的特殊用途有两种:
1.用来保存子程序的返回地址。
2.当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的位置继续执行。
当通过BL或者BLX指令调用子程序时,硬件自动将子程序返回地址保存在R14(LR)寄存器中,在子程序返回时,把LR的值赋值到程序计数器PC即可实现子程序返回(eg:MOV PC,LR)。
ADR指令:
这是一条小范围的地址读取伪指令,它将基于PC的相对偏移地址值读到目标寄存器中。
使用格式: ADR register,exper
在编译源程序时,编译器首先计算出当前PC到exper的偏移值#offset_to_exper,然后使用一条ADD或者SUB指令来替换这些伪指令,例如,ADD resister,PC,#offset_to_exper
注意标号exper与指令必须在统一代码段。
ADRL指令:
这是一条中等范围的地址读取伪指令,它将基于PC的相对偏移地址值读到目标寄存器中。
原理和ADR一样,不同的是它在编译的时候,会被用两条合适的指令来替换伪指令。
eg:ADD register,PC,offset1
ADD register,register,offset2
所以上面adrl r2, mem_cfg_val 意思是把下面那13个值的起始存储地址存入到r2寄存器。
.long:
定义一个4字节数据,并为它分配空间
.align n:
它的作用是对指令或者数据存放的地址按 2^n 进行对齐。下面是指定按 2^4 对齐。
汇编语言head.S:(作用是将 RAM 程序复制到 SDRAM中,并在SDRAM 中执行)
.equ MEM_CTL_BASE, 0x48000000 @ MEM_CTL_BASE 为芯片内存中的13个存储控制器中寄存器的起始地址.equ SDRAM_BASE, 0x30000000 @ SDRAM_BASE 为SDRAM在芯片中的内存地址.text.global _start_start:bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启bl memsetup @ 设置存储控制器(配置其相应的寄存器)bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中ldr pc,=on_sdram @ 跳转到SDRAM中继续执行on_sdram:ldr sp,=0x34000000 @ 设置堆栈bl mainhalt_loop:b halt_loopdisable_watch_dog:mov r1, #0x53000000 @ WATCHDOG在芯片中的内存地址mov r2, #0x0str r2, [r1] @ 把WATCHDOG寄存器写0mov pc, lr @ 把连接寄存器 lr 的值赋值给程序计数器 PC。用来子程序返回继续执行主程序copy_steppingstone_to_sdram:@ 我们这里将steppingstonede 4K数据全部复制到SDRAM中去@ steppingstone的 起始地址为0x00000000, SDRAM中的起始地址为0x30000000mov r1,#0ldr r2,=SDRAM_BASEmov r3,#4*1024 @ 因为我们要复制4K的大小1:ldr r4,[r1],#4 @ 从steppingstone 读取4字节的数据,然后让源地址加4str r4,[r2],#4 @ 将r4 里4字节的数据复制SDRAM中,然后目的地址加4cmp r1, r3 @ 参考我下面的解释bne 1bmov pc, lrmemsetup:mov r1, #MEM_CTL_BASEadrl r2, mem_cfg_val @ 注意这里 adr 后面是L 而不是数字1,反正我开始就是傻傻分不清。 @ 这个语句就是把 mem_cfg_val 段定义的几个数据的其实地址传递给 r2add r3, r1,#52 @ 把 r1+13*4 传递给r3,cpu是32bit的,即一个寄存器包含4个字节,所以13个就包含52个字节 @ 那么,如果把13个寄存器全部赋值结束后地址就应该是 r1+13*4。1:ldr r4, [r2],#4 @ 读取设置值,并让r2+4。 str r4, [r1],#4 @ 将此值写入寄存器,并让r1+4,以便下一个数据写入下一个寄存器 cmp r1, r3 @ 关于 cmp 指令其实也就是计算r1-r3,但是它的结果并不改变其寄存器的值,只是改变程序状态寄存器 CPSR的标志位 @ 然后下一条语句在指令后加上条件判断就能完成我们想要的循环。 bne 1b @ ne(如果不相等) 1b 这里的b(backwark),向后跳转到局部标签1处执行。 @ 相应的还有1f(foward),向前跳转到局部标签1处执行,注意理解这里的前和后,前代表地址增的方向,后代表地址减的方向 mov pc, lr.align 4mem_cfg_val:.long 0x22011110 @ BWSCON 寄存器要写入的值 .long 0x00000700 @ BANKCON0 寄存器要写入的值.long 0x00000700 @ BANKCON1 寄存器要写入的值.long 0x00000700 @ BANKCON2 寄存器要写入的值.long 0x00000700 @ BANKCON3 寄存器要写入的值.long 0x00000700 @ BANKCON4 寄存器要写入的值.long 0x00000700 @ BANKCON5 寄存器要写入的值.long 0x00018005 @ BANKCON6 寄存器要写入的值.long 0x00018005 @ BANKCON7 寄存器要写入的值.long 0x008C07A3 @ REFRSH 寄存器要写入的值.long 0x000000B1 @ BANKSIZE 寄存器要写入的值.long 0x00000030 @ MRSRB6 寄存器要写入的值.long 0x00000030 @ MRSRB7 寄存器要写入的值
c语言main函数:
#define GPFCON (*(volatile unsigned long *)0x56000050)#define GPFDAT (*(volatile unsigned long *)0x56000054)#define GPF4_out (1<<(4*2))#define GPF5_out (1<<(5*2))#define GPF6_out (1<<(6*2))void wait(volatile unsigned long dly) // 简单的延时函数{for(;dly>0;dly--);}int main(void){unsigned long i=0;GPFCON = CPF4_out | GPF5_out | GPF6_out; // 将LED对应的引脚设置为输出while(1){wait(30000);GPFDAT = (~(1<<4)); // 根据i的值,点亮LEDif(++1 == 8)i=0;}return 0;}
Makefile:
sdram.bin : head.S leds.Carm-linux-gcc -c -o head.o head.Sarm-linux-gcc -c -o leds.o leds.carm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elfarm-linux-objcopy -O binary -S sdram_elf sdram.binarm-linux-objdump -D -m arm sdram_elf > sdram.disclean:rm -f sdram.dis sdram_elf sdram.bin *.o
注: objdump 命令是Linux下的反汇编目标文件或者可执行文件的命令
-D 表示反汇编 (要反汇编的文件) 中的所有section-m 后面跟的cpu架构,arm就表示arm架构的cpu
> 表示将这个程序的反汇编文件西写入到led1.dis这个文件中,在终端中不显示出来
如果不加这个> ,那么你在终端上就可以看到输出的LED1_elf反汇编程序
阅读全文
0 0
- (嵌入式)关于arm中的存储控制器(三)终!
- (嵌入式)关于arm中的存储控制器(一)
- (嵌入式)关于arm中的存储控制器(二)
- 【嵌入式Linux+ARM】存储控制器(操作SDRAM)
- 嵌入式ARM设计历程(三)
- ARM------ 存储控制器
- 嵌入式Linux ARM汇编(三)——ARM汇编指令(三)
- 嵌入式arm学习总结(三)--IIC 基于AT24C02
- (三)搭建Fedora 嵌入式ARM宿主机环境
- 读书笔记| (三)ARM9 嵌入式学习:ARM实验篇
- 嵌入式面试题——ARM面试题(三)
- Android(三)数据存储之三SQLite嵌入式数据库
- arm存储控制器操作实例
- Qt/Embedded在嵌入式Linux系统中的应用(ARM)
- 嵌入式Linux ARM汇编(三)——ARM汇编指令(一)
- 嵌入式Linux ARM汇编(三)——ARM汇编指令(二)
- 嵌入式Linux ARM汇编(三)——ARM汇编指令(四)
- 嵌入式Linux ARM汇编(三)——ARM汇编指令
- D
- 基于比特币价差的统计套利策略
- 2017 多校训练第一场 KazaQ's Socks
- Android开发自定RadioGroup实现多布局重叠并单选&修改radioButton按钮样式
- redis3.0集群特性
- (嵌入式)关于arm中的存储控制器(三)终!
- Appium_swipe针对app模拟手机屏幕上下左右滑动操作方法
- [学习笔记] KMP算法的Next数组怎么求
- 用Python解析json数据
- JavaScript中级 (三) ----AJAX
- 三目运算符的一个坑-自动拆箱
- Linux 2.6.19.x内核编译配置选项简介
- ReduceByKey算子理解
- 正向代理与反向代理