基于Keil a51汇编 —— MPL 宏定义
MPL 宏
Ax51汇编程序支持的宏处理语言(MPL)是一种字符串替换工具,使您能够编写可修复的代码块(宏)并将其插入源文本中的一个或多个位置。
宏处理器查看源文件的方式与汇编程序不同。
- 对于汇编程序来说,源文件是一系列指令、语句和MCU指令。
- 对于宏处理器,源文件是一长串经过处理的字符。宏处理器扫描源文件以搜索对已定义宏的调用。宏调用将替换为内置或用户定义的宏。
MPL 的一个有价值的功能是条件组装。在宏中使用条件汇编会导致紧凑的配置相关代码,这对于良好的程序设计至关重要。此外,它还生成尽可能紧凑的代码。
注意:
- 宏处理在组装代码之前进行。它独立于程序集。宏时间不同于装配时间。因此,汇编程序知道的东西(如汇编语言符号、语言标签、使用 SET 和
EQU 语句定义的符号以及位置计数器)对于宏处理器来说是未知的。
MPL 宏概述
在汇编程序中使用 MPL 宏相对容易。
- 使用MPL用于启用 MPL 宏处理器的汇编程序指令。更重要的是,使某些MPL宏扩展不会被禁用诺宏命令。
- 定义要使用的宏。您可以创建一个包含文件,其中包含要在源文件之间共享的宏定义。
- 调用或调用程序源中定义的宏函数。宏处理器扩展汇编程序组装的宏函数(在宏处理时)。
所有 MPL 预定义和用户定义的函数都必须以元字符开头。默认情况下,元字符是百分比 (‘%’) 字符。但是,元字符可能会被元炭MPL 函数。
MPL 元字符
所有 MPL 预定义和用户定义的函数都必须以元字符开头。默认情况下,元字符是百分号 (‘%’)。但是,元字符可能会被元炭MPL 函数。
定义 MPL 宏
定义 MPL 函数创建一个宏。定义函数的语法为:
%DEFINE (macro-name <[>parameter-list<]>) (macro-body)%*DEFINE (macro-name <[>parameter-list<]>) (macro-body)
% | 是元字符用于指示宏函数 |
---|---|
* | 指定在文本模式下展开宏。 |
macro-name | 是宏的名称。宏名称最多可以包含 31 个字符,并且必须以 A-Z、a-z、_ 或 ?。后续字符可以是 A-Z、A-Z、_、?,或 0-9。 |
parameter-list | 是括在分隔符内并用分隔符分隔的参数列表。 |
macro-body | 是展开以替换宏名称和参数列表的文本。它可能包含对其他宏的调用。如果是这样,这些宏也会展开。定义宏时,在调用宏之前,宏主体中包含的那些宏调用不会展开。 |
注意:
- 创建宏后,可以通过后续的 DEFINE 函数重新定义它。
- 宏可以定义,也可以不带正式参数列表。
- 参数列表是一个相当自由格式的列表。指定时要小心。
不带参数的宏
没有参数(或参数)的宏定义如下:
%*DEFINE (macro-name) (macro-body)
该定义需要宏名称和在调用宏时展开的宏主体。例如,以下宏定义:
%*DEFINE (my_asdf) (asdf)
当调用时:
%my_asdf
扩展到:
asdf
带参数的宏
具有参数(或参数)的宏定义如下:
%*DEFINE (macro-name <[>parameter-list<]>) (macro-body)
参数列表列出了传递给宏的形式参数。参数列表中的参数在宏主体中用于在调用宏时填充值。这允许您设计为许多操作生成代码的泛型宏。
参数列表中的参数由唯一标识符(您选择的)指定,这些标识符由宏分隔符(通常是括号和逗号)分隔。参数列表括在括号内,各个参数用逗号分隔。这只是一个约定,而不是一个要求。
参数列表规范的唯一要求是宏参数的传递方式和定义宏时使用的分隔符相同。例如,以下宏定义中的参数列表:
%*DEFINE (BMOVE (src, dst, cnt)) (...)
是(src,dst,cnt)。若要调用此宏,必须使用相同的分隔符指定参数。例如:
%BMOVE (1, 2, 3)
但是,没有理由必须将参数括在括号内或必须用逗号分隔。例如:
%*DEFINE (BMOVE src dst cnt) (...)
若要调用此宏,必须按如下方式指定参数:
%BMOVE 1 2 3
宏主体中的参数用参数名称表示,前面是元字符(在上面的示例中为 %src、%dst 和 %cnt)。以下宏定义显示了一个更完整的示例
%*DEFINE (BMOVE (src, dst, cnt)) LOCAL lab (MOV R2,#%cntMOV R1,#%srcMOV R0,#%dst
%lab: MOV A,@R1MOV @R0,AINC R0INC R1DJNZ R2,lab
)
参数可以在宏主体中以任意次数和任意顺序使用。如果参数与宏同名并在宏正文中使用,则会展开该参数(而不是调用宏)。
如果宏与其中一个参数同名,则无法在宏主体中调用该宏,因为这会导致无限递归。
调用 MPL 宏
下面定义了一个名为 BMOVE 的宏,该宏采用三个参数:源、目标和计数。宏生成的代码将任意数量的字节从内存的一部分复制到另一部分。
%*DEFINE (BMOVE (src, dst, cnt)) LOCAL lab (MOV R2,#%cntMOV R1,#%srcMOV R0,#%dst
%lab: MOV A,@R1MOV @R0,AINC R0INC R1DJNZ R2,lab
)
若要调用此宏,请指定元字符后跟宏名称和参数列表(如果有)。实际参数必须具有平衡的文本,并且可以包含对其他宏的调用。例如,可以按如下方式调用上述宏:
%BMOVE (array1,array2,10)
宏扩展为:
MOV R2,#10MOV R1,#array1MOV R0,#array2
??LAB?0: MOV A,@R1MOV @R0,AINC R0INC R1DJNZ R2,??LAB?0
注意:
- 上面的示例会产生程序集错误,因为源文件不包含节定义。
- 这GEN和GENONLY指令可用于在汇编程序列表文件中包括宏定义和宏调用。
局部符号
MPL 宏可能包括作为分支目标的本地标签。固定的标签名称会导致错误,如果多次调用宏。发生这种情况是因为同一标签名称在源文件中只能使用一次。此问题可以通过使用局部符号来解决。本地宏符号附加一个唯一的序列号,每次调用宏时,该数字都会递增。
必须在宏定义行中声明本地符号:
%*DEFINE (macro-name <[>parameter-list<]>) <[>LOCAL local-list<]> (macro-body)
其中,本地列表是宏的本地符号的列表(用逗号或空格分隔)。
局部符号在宏宏体中使用时必须以元字符为前缀。例如:
%*DEFINE (BMOVE (src, dst, cnt)) LOCAL lab (MOV R2,#%cntMOV R1,#%srcMOV R0,#%dst
%lab: MOV A,@R1MOV @R0,AINC R0INC R1DJNZ R2,lab
)
表达式
MPL 宏处理器将平衡文本字符串解释为数值表达式,当它们用于以下 MPL 函数的参数时:
- EVAL
- IF
- REPEAT
- SUBSTR
- WHILE
数值表达式的处理方式如下:
- 表达式的文本以计算宏函数参数的普通方式展开。
- 生成的字符串被计算为一个数值,该数值被转换为表达式值(表达式的最终值)的字符表示形式。数值表达式中可以使用以下运算符:
- Parentheses()
- HIGH,LOW
- *, /, MOD, SHL, SHR
- EQ, LT, LE, GT, GE, NE
- NOT
- AND,OR,XOR
MPL 数值表达式的算术是使用有符号 16 位整数执行的。关系运算符的结果为 0 (FALSE) 或 1 (TRUE)。
数值常量
可以使用下表中指定的后缀和字符以十六进制(以 16 为基数)、十进制(以 10 为基数)、八进制(以 8 为基数)和二进制(以 2 为基数)指定数字:
字符常量
MPL 宏处理器支持 ASCII 字符串,这些字符串可能包含一个或两个用单引号 (“'”) 括起来的字符。例如:
注意:
宏处理器无法访问汇编程序的符号表。因此,在宏处理过程中,标签以及 SET 和 EQU 符号的值是未知的。但是,您可以使用设置宏函数来定义宏符号。
相关文章:
基于Keil a51汇编 —— MPL 宏定义
MPL 宏 Ax51汇编程序支持的宏处理语言(MPL)是一种字符串替换工具,使您能够编写可修复的代码块(宏)并将其插入源文本中的一个或多个位置。 宏处理器查看源文件的方式与汇编程序不同。 对于汇编程序来说,源…...
Android 13 骁龙相机点击拍照流程分析(二)——点击拍照到存入相册
一.前言 本篇是在Android 13 骁龙相机点击拍照流程分析(一)——点击拍照到更新到左下角缩略图文章的基础上进行延申的,前面的预览、点击拍照的过程参考第一篇:Android 13 骁龙相机点击拍照流程分析(一)——点击拍照到更新到左下角缩略图-CSDN博客 二.生成图片并保存 从第…...
常见算法-巴斯卡三角形(Pascal)
常见算法-巴斯卡三角形(Pascal) 1、说明 巴斯卡(Pascal)三角形基本上就是在解 nCr,因为三角形上的每一个数字各对应一个nCr,其中 n 为 row,而 r 为 column,如下: 0C0 1…...
AI:09-基于深度学习的图像场景分类
图像场景分类是计算机视觉领域的重要任务之一,它涉及将图像分为不同的场景类别,如城市街景、山脉风景、海滩等。本文将介绍基于深度学习的图像场景分类方法,并提供相应的代码实例,展示了深度学习在图像场景分类中的技术深度和应用前景。 图像场景分类是计算机视觉中的一项…...

uni-app:引入echarts(使用renderjs)
效果 代码 <template><view click"echarts.onClick" :prop"option" :change:prop"echarts.updateEcharts" id"echarts" class"echarts"></view> </template><script>export default {data()…...

使用wireshark解析ipsec esp包
Ipsec esp包就是ipsec通过ike协议协商好后建立的通信隧道使用的加密包,该加密包里面就是用户的数据,比如通过的语音等。 那么如何将抓出来的esp包解析出来看呢? 获取相关的esp的key信息. 打开wireshark -> edit->preferences 找到pr…...
linux如何删除最近操作的日志
Linux系统下,不同的应用程序可能会生成不同的日志文件。如果你想要删除最近一段时间内的操作日志,可以使用一些命令来完成。 以下是一些常见的命令: dmesg:该命令用于显示内核环境下的运行信息和警告信息。如果你需要清空dmesg缓…...
android端MifareClassicTool
github地址 GitHub - ikarus23/MifareClassicTool: An Android NFC app for reading, writing, analyzing, etc. MIFARE Classic RFID tags. 开源项目 下载: https://www.icaria.de/mct/releases/ 功能 1、读取Mifare Classic卡片 2、编辑并保存卡片的数据 3、写入Mifare C…...

设计模式 - 迭代器模式
目录 一. 前言 二. 实现 三. 优缺点 一. 前言 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按…...

Docker之Dockerfile搭建lnmp
目录 一、搭建nginx 编辑 二、搭建Mysql(简略版) 三、搭建PHP 五、补充 主机名ip地址主要软件mysql2192.168.11.22Docker 代码示例 systemctl stop firewalld systemctl disable firewalld setenforce 0docker network create --subnet172.18.…...

排序算法——选择排序
一、介绍: 选择排序就是按照一定的顺序从选取第一个元素索引开始,将其储存在一个变量值中,根据排序规则比较后边每一个元素与这个元素的大小,根据排序规则需要,变量值的索引值进行替换,一轮遍历之后&#x…...
【数据结构C/C++】双向链表的增删改查
文章目录 CC408考研各数据结构C/C代码(Continually updating) 对我个人而言,在开发过程中使用的比较多的就是双向链表了。 很多重要的代码优化都会使用到基于双向链表实现的数据机构。 比如我们常用的HashMap,我们知道Key其实是无…...

Godot 添加Nuget 引用
前言 我的Godot 专栏 我在之前的文章中,解决了Visual Studio 如何去调试正在运行的Godot 程序。Godot 对于C# 的支持只剩下一个,那就是Nuget 添加。 Godot VisualStudio外部编辑器设置 添加Nuget Nuget 添加还是非常的容易的。我们直接添加一个最常用的…...

IC工程师职场必备《经典Verilog100多个代码案例》(附下载)
对于IC行业的人员而言,Verilog是最基础的入门,用于数字电路的系统设计,很多的岗位都会用到,可对算法级、门级、开关级等多种抽象设计层次进行建模。 Verilog由于其简单的语法,和C语言的相似性,目前被各大公…...

springboot项目做成公共项目
一:引言 最近碰到个需求,就是把我项目做成一个公共的提供jar包给别人使用,我也是捣鼓了一段时间去研究这个问题,这个东西其实就是A 项目提供jar包给B项目,B项目只要引入A项目的jar包就可以使用A项目的功能。 问题一&…...

RTC 时间、闹钟
实时时钟RTC是一个独立的定时器。RTC模块拥有一个连续计数的计数器,在软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。 在掉电情况下 RTC仍可以独立运行 只要芯片的备用电源…...

【yolo系列:yolov7训练添加spd-conv】
系列文章目录 yolov7训练添加spd-conv 文章目录 系列文章目录一、spd-conv是什么?二、使用步骤1.第一步:先在models/common.py加上2.第二步:models/yolo.py加上2.第三步:修改yolov7的yaml文件 总结 提示:以下是本篇文…...

面向对象设计-UML六种箭头含义
目录 UML概述UML语义UML表示法 六种常用关系标识方法泛化实现依赖关联聚合组合 本文参考文章 https://blog.csdn.net/qq_25091281/article/details/123801862 UML概述 UML (Unified Modeling Language)为面向对象软件设计提供统一的、标准的、可视化的建模语言。适用于描述以…...

一本没有任何数学公式的自然语言处理入门书
ChatGPT 时代来了,AI 从旧时王谢堂前燕,飞入寻常百姓家。越来越多非 AI 领域 的软件开发者涌进 NLP(自然语言处理)领域。在这个快速发展的时代,如果这些软件开发 者要像读书那样先读 4 年本科、2 年硕士、3 年博士才能搞 AI,风口早…...
【数据结构C/C++】多维数组的原理、访问方式以及作用
文章目录 什么是多维数组?代码讲解使用方式为什么指针遍历的方式是这样子的?(助你理解指针的含义)使用场景408考研各数据结构C/C代码(Continually updating) 什么是多维数组? 在C语言中&#x…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...