JZ Assembly Static Checker
Project description
jzcheck
JZ Assembly Static Checker — JZ8 系列 OTP 微控制器汇编静态分析工具。
提供 CLI 链接器(基于 .mpj 项目文件的完整检查)、LSP 服务器(VS Code IDE 集成)、代码格式化器 三大功能。
安装
从源码安装
pip install .
从 .whl 文件安装
先打包生成 .whl 文件:
# 安装构建工具
pip install build
# 构建 wheel 包(产物在 dist/ 目录下)
python -m build --wheel .
或使用项目根目录下的打包脚本(自动清理旧产物):
# Windows
build_jzcheck.bat
安装 .whl 文件:
pip install dist\jzcheck-0.1.0-py3-none-any.whl
也可将 .whl 拷贝到其他机器离线安装:
pip install jzcheck-0.1.0-py3-none-any.whl
卸载:
pip uninstall jzcheck
开发模式安装(源码修改即时生效)
pip install -e .
快速开始
# 检查项目文件(仅支持 .mpj 模式,不支持独立 .asm)
jzcheck project.mpj
# 指定芯片 XML 配置目录
jzcheck -x config/ project.mpj
# 静默模式(只显示 error 和 warning)
jzcheck -q project.mpj
# 警告视为错误
jzcheck -w project.mpj
# 显示详细堆栈分析
jzcheck --stack-detail project.mpj
命令行参数
| 参数 | 说明 |
|---|---|
mpj |
.mpj 项目文件(必填) |
-x / --xml-dir |
芯片 XML 配置目录(默认使用内置 config/) |
-q / --quiet |
静默模式,抑制 info 级别消息 |
-w / --warnings-as-errors |
将警告视为错误 |
--stack-detail |
显示详细堆栈分析路径信息 |
--version |
显示版本号 |
LSP 服务器
jzcheck-lsp
使用 pygls 协议,配合 VS Code 扩展提供 IDE 特性:
| 特性 | 说明 |
|---|---|
| 诊断 | 打开/编辑时实时推送词法、语法、语义、内存诊断 |
| 代码补全 | 指令、寄存器、符号、位索引补全 |
| 悬停信息 | 指令文档、符号定义、宏展开、寄存器位字段 |
| 跳转到定义 | 符号、宏、寄存器的定义位置 |
| 文档符号 | 标签 + EQU 常量的大纲视图 |
| CodeLens | 函数上方显示静态堆栈深度 |
| 代码格式化 | 规范化缩进、大小写、对齐 |
| 符号重命名 | 跨文件标签、EQU 常量、宏名重命名 |
诊断代码
| 代码 | 级别 | 含义 |
|---|---|---|
| E001 | 错误 | 词法错误(无效字符、无效十六进制、无效立即数) |
| E002 | 错误 | 语法错误(未知指令、意外的行首标记) |
| E003 | 错误 | 操作数不匹配 |
| E005 | 错误 | 未定义符号 |
| E006 | 错误 | 重复符号/标签 |
| E011 | 错误 | 宏展开深度超过限制(100 层) |
| E013 | 错误 | 跳转目标超出 ROM 范围 |
| E015 | 错误 | 程序超出 ROM 大小 |
| E016 | 错误 | CALL/JMP 到未定义标签/函数 |
| E999 | 错误 | 内部分析错误 |
| W001 | 警告 | 标识符超过 32 个字符 |
| W003 | 警告 | 宏参数数量不匹配 |
| W005 | 警告 | 堆栈深度达到/超过芯片限制 |
| W007 | 警告 | 递归调用检测 |
| W009 | 警告 | ISR 嵌套风险(中断内启用 EI) |
| W010 | 警告 | 主程序 + 中断组合超过堆栈限制 |
| W011 | 警告 | 函数缺少 RET/RETI/RETL |
| W012 | 警告 | CALL/RET 不平衡 |
| W013 | 警告 | 函数内混合返回类型 |
| W014 | 警告 | ORG 区域重叠 |
| I002 | 信息 | 孤立函数(已定义但从未调用) |
| I003 | 信息 | 流水线进度消息 |
检查内容
词法/语法检查
- 非法字符检测(含编码自动检测 UTF-8/GBK)
- 助记符拼写错误(68 个名称 / 43 个基础助记符 + 24 个 EM78P153 别名 + INT,81 种操作数模式)
- 操作数数量/格式/模式匹配验证
- 数值格式错误(如
0xGG) - 标签名合法性、标识符长度限制(32 字符)
- 三种注释风格:
//、;、/* */
宏处理
- MACRO/ENDM 定义解析,支持参数、嵌套、LOCAL、EXITM
- 参数替换展开(大小写不敏感匹配)
- 嵌套宏递归展开,深度上限保护(100 层)
- 重复宏定义检测、参数数量验证
- 条件指令:
IF/ELSE/ENDIF、IFB/IFNB/IFDEF/IFNDEF/IFIDNI/IFDIFI/ELSEIF - 重复块:
REPT、FOR、FORC - 运行时指令:
ERROR、ECHO、VARARG、EXPAND
语义检查(2-pass 分析)
- 第 1 遍:构建符号表(标签 + EQU 定义)
- 第 2 遍:交叉引用检查、寻址模式验证
- 未定义符号检测、重复定义检测
- ORG 地址跟踪、EQU 表达式求值(支持十六进制/二进制/符号引用/
$PC) - 位操作符号解析(
REG.BIT链式追踪) - 跳转/调用目标范围验证(
$+N/$-N) - EM78P153 兼容别名(24 个)支持
内存检查
- ROM 越界检查(基于芯片配置)
- RAM 分配范围检查(用户 RAM vs 专用寄存器)
- RAM 地址重叠检测、ORG 区域重叠检测
- 用户 RAM 与专用寄存器冲突检查
- 寄存器地址冲突检查
堆栈静态分析(5 阶段)
- 函数构建 + 调用图:按标签分割函数,提取调用关系
- 调用图遍历:路径敏感 DFS 深度计算,循环/递归检测
- 中断分析:ISR 检测、嵌套风险分析
- 泄漏检测:缺失 RET、CALL/RET 平衡、混合返回类型
- 综合报告:主程序 + 中断组合深度、最差路径
代码格式化
- 幂等格式化(
format(format(x)) == format(x)) - 规范化缩进、指令大小写、寄存器大小写、十六进制大小写
- 四列对齐(标签/指令/操作数/注释)
- 对注释无损(含
/* */块注释)
支持的芯片
内置 40 种 JZ8 系列芯片配置(位于 jzcheck/config/),包括:
| 系列 | 型号 |
|---|---|
| JZ8F | 8003, 8620, FT4801, FT8801 |
| JZ8M | 1602, 2532, 2605, 2632, 4600, 4601 |
| JZ8P | 0510, 1503S, 1507, 1510, 1520, 1521, 1525, 153, 1530, 1531, 155, 1611, 2506, 2508, 2521, 2600, 2610, 2612, 2613, 2615, 2616, 5308, 5318, E155E, E255E |
| JZ8PT | 2500, 2503 |
| JZSP | 4001, 4002, 8001 |
默认芯片:JZ8P1520(14 位指令宽度,1024 字节 ROM,80 字节 RAM,5 级堆栈)
支持的语法
- 注释:
//、;、/* ... */ - 立即数:
@前缀(如@0xff、@30、@TCC_NUM) - 数值:十六进制
0x/0X、二进制0b、十进制 - 位寻址:
REG.BIT语法(如FLAG_FUCTION_0.0、STATUS.7) - 相对寻址:
$、$+N、$-N - 伪指令:
EQU、ORG、INCLUDE - 宏:
MACRO/ENDM、LOCAL、EXITM、VARARG、EXPAND - 条件:
IF/ELSE/ENDIF、IFB、IFNB、IFDEF、IFNDEF、IFIDNI、IFDIFI、ELSEIF - 重复:
REPT、FOR、FORC - 运行时:
ERROR、ECHO - 指令集:43 个基础助记符 + 24 个 EM78P153 兼容别名 +
INT= 68 个可识别的名称,共 81 种操作数模式变体
架构
jzcheck/
├── cli.py # CLI 入口 + 流水线编排(.mpj 解析 → 检查)
├── lexer.py # 词法分析器(编码检测 + Tokenizer)
├── parser.py # 语法解析器 + EQU 表达式求值器 + .mpj 解析
├── macro.py # 宏处理器(定义收集 + 参数展开 + 条件指令)
├── semantics.py # 语义分析器(2-pass 符号表 + 寻址检查)
├── memory.py # 内存分配检查器(ROM/RAM/ORG)
├── stack.py # 堆栈深度静态分析器(5 阶段)
├── instructions.py # JZ 指令集数据库(43 助记符 / 81 模式)
├── chipdb.py # 芯片配置数据库(XML 解析 + 查询)
├── reporter.py # 诊断报告引擎(三级 + 定位 + 退出码)
├── includer.py # INCLUDE 路径解析器
├── formatter.py # 代码格式化器(幂等规范化)
├── lsp_server.py # LSP 服务器入口(pygls)
├── lsp_project.py # LSP 工作区管理器(多文件符号管理)
│
├── config/ # 40 种芯片 XML 配置文件
│ ├── JZ8P1520.XML # 默认芯片
│ └── *.XML
│
└── lsp_features/ # LSP 功能模块
├── diagnostics.py # 诊断适配器 + 分析缓存
├── completion.py # 代码补全提供者
├── hover.py # 悬停信息提供者
├── definition.py # 跳转到定义提供者
├── symbols.py # 文档符号提供者
├── codelens.py # CodeLens(堆栈深度显示)
└── rename.py # 符号重命名提供者
数据流
.mpj 项目文件
│
├── parser.parse_mpj() → 芯片型号、源文件列表、头文件列表
├── chipdb.load_chip() → 芯片配置(ROM/RAM/寄存器)
│
├── [头文件预处理 - 共享 MacroProcessor + SemanticAnalyzer]
│ ├── lexer.tokenize_source() → Token 流
│ ├── macro.collect_definitions() → 提取宏定义
│ ├── macro.expand_all() → 展开宏调用
│ ├── parser.parse_lines() → ParsedLine 列表
│ └── semantics.build_symbol_table() → 符号表
│
├── [源文件处理 - 第 1 遍]
│ └── semantics.build_symbol_table() → 收集标签
│
├── [源文件处理 - 第 2 遍]
│ ├── semantics.check_references() → 交叉引用验证
│ ├── memory.check_program() → 内存分配检查
│ └── stack.StackAnalyzer.analyze() → 5 阶段堆栈分析
│
└── reporter.flush() → 排序输出诊断 + 退出码
测试
# 运行全部测试(18 个测试文件)
python -m pytest tests/ -v
# 按模块运行
python -m pytest tests/test_lexer.py -v
python -m pytest tests/test_parser.py -v
python -m pytest tests/test_stack.py -v
python -m pytest tests/test_pipeline.py -v
测试覆盖:词法分析、语法解析、宏处理、语义分析、内存检查、堆栈分析、格式化、诊断适配、CodeLens、重命名、端到端流水线。
已知限制
- 位表达式符号(如
BIT_TCC EQU FLAG_FUCTION_0.0)需要符号表解析才能正确验证位操作指令 - 多文件项目模式下跨文件符号引用需要后续增强
- SONIX 兼容宏库(macro1-3.ash)暂不支持
- 仅支持
.mpj项目模式,不支持独立的.asm文件检查
许可证
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jzcheck-0.7.0-py3-none-any.whl.
File metadata
- Download URL: jzcheck-0.7.0-py3-none-any.whl
- Upload date:
- Size: 224.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc3f92af0ccf0eab54b4262811d329614ce6ef884f1745f7ab961acc786d70db
|
|
| MD5 |
17e2ee0087e3e2e19931ec943da03044
|
|
| BLAKE2b-256 |
33e07920fd2168d9e281767ae21fc04e206ccc6031603a23821d38364f58c421
|