Skip to main content

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/ENDIFIFB/IFNB/IFDEF/IFNDEF/IFIDNI/IFDIFI/ELSEIF
  • 重复块:REPTFORFORC
  • 运行时指令:ERRORECHOVARARGEXPAND

语义检查(2-pass 分析)

  • 第 1 遍:构建符号表(标签 + EQU 定义)
  • 第 2 遍:交叉引用检查、寻址模式验证
  • 未定义符号检测、重复定义检测
  • ORG 地址跟踪、EQU 表达式求值(支持十六进制/二进制/符号引用/$ PC)
  • 位操作符号解析(REG.BIT 链式追踪)
  • 跳转/调用目标范围验证($+N/$-N
  • EM78P153 兼容别名(24 个)支持

内存检查

  • ROM 越界检查(基于芯片配置)
  • RAM 分配范围检查(用户 RAM vs 专用寄存器)
  • RAM 地址重叠检测、ORG 区域重叠检测
  • 用户 RAM 与专用寄存器冲突检查
  • 寄存器地址冲突检查

堆栈静态分析(5 阶段)

  1. 函数构建 + 调用图:按标签分割函数,提取调用关系
  2. 调用图遍历:路径敏感 DFS 深度计算,循环/递归检测
  3. 中断分析:ISR 检测、嵌套风险分析
  4. 泄漏检测:缺失 RET、CALL/RET 平衡、混合返回类型
  5. 综合报告:主程序 + 中断组合深度、最差路径

代码格式化

  • 幂等格式化(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.0STATUS.7
  • 相对寻址$$+N$-N
  • 伪指令EQUORGINCLUDE
  • MACRO/ENDMLOCALEXITMVARARGEXPAND
  • 条件IF/ELSE/ENDIFIFBIFNBIFDEFIFNDEFIFIDNIIFDIFIELSEIF
  • 重复REPTFORFORC
  • 运行时ERRORECHO
  • 指令集: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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jzcheck-0.7.0-py3-none-any.whl (224.7 kB view details)

Uploaded Python 3

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

Hashes for jzcheck-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fc3f92af0ccf0eab54b4262811d329614ce6ef884f1745f7ab961acc786d70db
MD5 17e2ee0087e3e2e19931ec943da03044
BLAKE2b-256 33e07920fd2168d9e281767ae21fc04e206ccc6031603a23821d38364f58c421

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page