问题: 有些芯片输出的电流非常弱 ------> 引脚驱动能力不足? 解决:使用三极管来进行放大:
分析:同名的称之为网络, 同名的网络是连在一起的。
启动过程: 1、设置为norflash启动: cpu直接从norflash 读取指令执行。
注:设置为谁启动,谁的基地址就是 0, norflash启动的时候,片内SRAM 还可以进行访问,他的地址为 0x4000 0000;
2、设置为nandflash启动: cpu不可以直接从 nandflash 读取数据。
但是我们硬件,会自动复制nandflash 的前4K 内存 到片内RAM。 然后cpu ,再从片内 RAM 执行代码。
注:nandflash 启动的时候,norflash 不可以进行访问。
1、cpu 有自己的通用寄存器:R0 — R15。 2、各个外设有自己的 SFR :专用寄存器。
区别: 1、cpu可以通过 R0 寄存器的名称,直接访问。 2、但是 cpu 访问 SFR ,必须通过对应的地址来进行访问。
缺点: 这些直接操作,虽然我们将我们需要的位置1,但是我们同时也清除了其他位。 (影响了其他位。)
注: 1、非法立即数
MOV R0 #123456789 这个指令是错误的(后面汇编与指令码中讲解)初步解析:ARM的一条指令最终会被编译成 32 的机器指令,如果是一个非常大的数放不下。
2、引入伪指令:就是不是真实的汇编指令, 在被编译的时候,会被改成真正的汇编指令。
伪指令:就是加一个 ”=“ 等于号
LDR R0 =0X12345678解释汇编伪指令
通用寄存器的别名:
注: 1、pc(program count ) 程序计数器是什么东西? 其实是 通用 R15寄存器的别名。
2、流水线 — arm为三级流水线(为了节省cpu的时间) 假设当前在执行 A 地址处的机器指令, 那么当前就在对 A+4 地址处的机器指令进行译码。 最后 PC指针正在读取 A+8 地址处的机器指令。
mov 机器码格式
1、计算: 2、八进制和十六进制 与二进制的关系。 3、二进制,八进制,十六进制如何快速转换
1、普通变量,指针变量, 任何一个变量,在内存中都占有一块区域。
2、如何操控内存。
直接通过变量名 int a; a = 123;解析: 就是从 变量a 地址处开始,往后面延续 4个字节的大小,然后写入 123。 两个要点: (1)往后延续多长:由变量名的类型决定, int (2)写入多少: 由赋值决定。
通过指针来操控内存 int *p1; p1 = &a; *p1 = 234;三个要点: (1)从哪个地址开始: &a (2)延续多长:int * (4个字节) (3)写入多少: 234
总结:使用指针来写入寄存器
这里有一个错误: unsigned int * 的指针 不可以直接赋值 int类型的数字。 要加上强制转化(骗过编译器)。
在我们的逻辑程序当中, main函数在启动代码(汇编文件)当中调用。
要明白,局部变量被保存在 栈当中。
引入新的汇编指令:
sub,add想要分清楚,最后是改变谁。---- 最终改变的是目的操作数。
add r0, r1, #4 r0 = r1 + 4 sub r0, r1, #4 r0 = r1 - 4 sub r0, r1,r2 r0 = r1 - r2 b 和 bl 指令 bl :brarch and link。(1) 跳转到 XXX (2) 将返回地址保存在 lr 寄存器当中。 返回地址 : 下一条指令的地址。
ldm 和 stm指令ldm:load many ,读内存,写入多个寄存器 stm :store many ,把多个寄存器的值写入内存,
ldmia: stmdb:
后缀: ia ,ib ,da , db 的含义 举例:
stmdb sp!, {fp,ip,lr,pc}db : 就是先减后存的意思。
注: { }里面的寄存器,怎么排序无所谓, 存放规则: 高编号寄存器存在高地址处。
ldmia sp, {fp,sp,pc}ia :先读取后增加。 没有 ! :意思就是 sp 虽然移动但是不改变自己本身的值。
理解:就是将 sp 指针指向内存的值, 读取到寄存器当中。 ---- 本质就是恢复原来函数的现场。
1、整体浏览程序框架
问题:
我们代码和局部变量怎么存放? 代码–机器指令 (放到内存中----称之为代码段) 变量–变量的值 (放到内存中----称之为栈)
1、调用 “main” 函数时候,保存一个地址到 lr 寄存器当中, 返回什么地址?
2、在 C语言函数的开头,汇编帮我们做了些什么? 将fp ,lr ,ip ,pc 寄存器压入栈:
