gentleman
发表于 2023-9-9 15:07:15
本帖最后由 gentleman 于 2023-9-23 09:01 编辑
2023/09/05 第三十六集
接上回,继续讲那四个关键字
_at_ 指定变量再决定存储器位置
单片机特有
sturct num edata x_at_0x0200;
这行就把num 放在edata 区域0x0200位置
看到watch 窗口的变量的地址
提到结构体 ,就是一堆变量放一起了
用的时候可以直接.
arm 很多寄存器 都用结构体
指针
near 指针huge指针
寻址范围不同
指针能强制转换
这些能转,其他非法
gentleman
发表于 2023-9-23 09:17:44
2023/09/01 第三十一集
mcs251 程序和数据支持多个物理空间分离的存储空间
这里脑子里应该出现一张图
这个c语言比标准c多了一些 表示不同存储空间的标识符
计算机系统 中都放在同一物理存储空间程序--》 sram(cache)
单片机 不同存储空间 edataxdata(略慢) code(放程序常数)
CODE
64k
代码空间大
程序代码
常熟变量
标识符 code
stc32g 最好不用code 用const near 或 const far
DATAIDATA
data 前128字节
idata 256字节
位寻址20h开始 16字节
idata 标识符
data bdata ebdata
gentleman
发表于 2023-9-23 09:31:14
2023/09/01 第三十二集
前面是程序的反汇编分析
片内外的 数据存储器可R/W
stc32g 有XRAM
可以有64k 外部数据存储器
但可能是外设-----存储器映射IO
sfr 80H~FF, PWM USB ...
CPU 访问外设SFR
存储器映射io (XSFR?)
可以写程序定义上面的这些变量,反汇编看看到底放在哪里了
near memroy
00:0000~00:ffff
edata /econst
用near 声明
far完整地址范围16M
huge大存储器16M-1
SFR 与外设交互
只能直接访问
gentleman
发表于 2023-9-23 10:06:51
2023/09/01 第三十三集
数据类型
注意int是16位
void 无返回值
int 不同架构 不一样
可以加关键字约束
enum
枚举
浮点在内存中这么存
_chkfloat_允许 快速检查
union f {
float f;
unsigned long ul;
}
这里学了一手 可以在调试时用printf 打印变量
double
默认是float 不是double
位寻址
bata/edata
位寻址能力很强
sfr 特殊
sfr
sfr P0 = 0X80
函数体外声明
sbit
^ 定义位
gentleman
发表于 2023-9-29 13:40:24
三十四集到三十六集在前面
gentleman
发表于 2023-9-29 14:29:37
2023/09/08 第三十七集
定义了个 edata区域 的指针
指向xdata 区域的变量 a
查看反汇编定义变量
A5立即数搬到 A
DPTR 指针指向 0x0000(这里dpxl 是0x01段)
A 移到DPTR 指向的内存
memory窗口 在0x010000 发现立即数A5
给指针赋值
WR6 WR4 复制
查看DR4的值就是变量的地址
吧DR4 搬到 edata 0x0008位置单元
通过一个简单的小程序,解释指针在底层是如何实现的
指针有16位 32位的
指针指向的是地址
函数
实参如何传入形参
返回值如何返回
这里是进入/退出函数 时要保存/退出现场的数据
函数声明格式
arm架构里attribute属性 那行内容更多
reentrant 可重用被两个引用或递归
interrupt 中断 这里吐槽一下keil只支持31个中断号,超过就要用拓展工具或用汇编借用其他的中断号
arm存储器外设统一编址
stc 有一部分是, 其他的在sfr中
可以根据具体函数内容来选择 small large 模型
8个寄存器组--老朋友了
处理中断或实时操作系统时很有用
可以切寄存器组, 不用堆栈
中断函数
不允许 带有运算符和中断属性的表达式
这里写个标志位就行,别放太多东西,消耗寄存器,堆栈
ISR-RETI别记错了
中断函数不能通过指针调用
gentleman
发表于 2023-9-29 14:49:56
本帖最后由 gentleman 于 2023-9-29 15:06 编辑
2023/09/08 第三十八集
可重入函数
递归/多个进程用
不用用位类型参数
不能用alien属性
-PL/M 函数必须用alien
外来函数
RTX51-TINY现在C251编译器没了
操作系统
-轮询调度
抢夺调度
互斥
锁
task 任务
prority 优先级
函数参数
通过寄存器(通常)/固定存储器传递参数
可以用REGPRAMS /NOREGPRAMS使能/禁止 寄存器传参
c汇编混合编程文档能找到
寄存器最多穿9个参数R0~R7R11
返回值
也是拿寄存器返回
gentleman
发表于 2023-9-29 15:06:08
2023/09/ 12第三十九集
这节课还是看反汇编代码
定义一个 求和函数 返回 char a ,short int b ,long int c 的和
重点在函数调用这里
LCALL 调用子程序
子程序在这
这里吧参数从寄存器又搬了一次
放在函数运行中对原来的寄存器进行误操作
后面的符号拓展求和等 就比较熟悉了
下一个例子 寄存器不够了
放到存储器了
看图
放到存储器后,吧DR4释放出来
gentleman
发表于 2023-10-1 15:29:34
2023/09/ 12第四十集
数组名 是地址
冒泡排序算法--应该是叫这个吧
调用子程序这里 吧数组地址放在寄存器里
这里通过反汇编可以看到数组都是间接寻址
在memory窗口可以看到数组
就是说数组一直在存储器,寄存器放不下
下个例子字符串拼接
字符串结尾是‘\0’
没到‘\0’就一直挪指针
到了就把字符拼接上
最后补上'\0'
看一下while 循环
用的SJMPJNZ
直到 R11 寄存器为0
说明字符串结束
下一部分是reentrant 可重入
例子用的是递归
首次调用 入栈
依次调用
gentleman
发表于 2023-10-1 15:50:33
2023/09/ 12第四十一集
_attribute_
-alias 别名 变量/函数
感觉有点像#define
看到了这两个是完全相同的地址空间
函数也可以用
laigned(n)对齐
noreturn函数远不要返回
头文件
#include
告诉c预处理包含编译器输入流中指定的文件内容
多次包含可能有错
所以用#ifndef xxx
#define xxx
#endif
宏
减少书写量,不会减少flash
还有带参数的宏
可变参数宏
代操作符的宏
##操作符
这一堆是预定义的宏