基于Keil a51汇编 —— MPL 宏定义

MPL 宏

Ax51汇编程序支持的宏处理语言(MPL)是一种字符串替换工具,使您能够编写可修复的代码块(宏)并将其插入源文本中的一个或多个位置。

宏处理器查看源文件的方式与汇编程序不同。

  • 对于汇编程序来说,源文件是一系列指令、语句和MCU指令。
  • 对于宏处理器,源文件是一长串经过处理的字符。宏处理器扫描源文件以搜索对已定义宏的调用。宏调用将替换为内置或用户定义的宏。

MPL 的一个有价值的功能是条件组装。在宏中使用条件汇编会导致紧凑的配置相关代码,这对于良好的程序设计至关重要。此外,它还生成尽可能紧凑的代码。

注意:

  • 宏处理在组装代码之前进行。它独立于程序集。宏时间不同于装配时间。因此,汇编程序知道的东西(如汇编语言符号、语言标签、使用 SET 和
    EQU 语句定义的符号以及位置计数器)对于宏处理器来说是未知的。

MPL 宏概述

在汇编程序中使用 MPL 宏相对容易。

  1. 使用MPL用于启用 MPL 宏处理器的汇编程序指令。更重要的是,使某些MPL宏扩展不会被禁用诺宏命令。
  2. 定义要使用的宏。您可以创建一个包含文件,其中包含要在源文件之间共享的宏定义。
  3. 调用或调用程序源中定义的宏函数。宏处理器扩展汇编程序组装的宏函数(在宏处理时)。

所有 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 符号的值是未知的。但是,您可以使用设置宏函数来定义宏符号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/98809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UniAD 论文学习

一、解决了什么问题&#xff1f; 当前的自动驾驶方案大致由感知&#xff08;检测、跟踪、建图&#xff09;、预测&#xff08;motion、occupancy&#xff09;和规划三个模块构成。 为了实现各种功能&#xff0c;智驾方案大致包括两种路线。一种是针对每个任务都部署一个模型&a…

Python Parser 因子计算性能简单测试

一直以来&#xff0c;Python 都在量化金融领域扮演着至关重要的角色。得益于 Python 强大的库和工具&#xff0c;用户在处理金融数据、进行数学建模和机器学习时变得更加便捷。但作为一种解释性语言&#xff0c;相对较慢的执行速度也限制了 Python 在一些需要即时响应的场景中的…

读取 yaml 文件

一、引入依赖 <dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.32</version> </dependency> 二、读取yaml内容工作代码 &#xff08;1&#xff09;上传yaml文件 读取yaml文件并校验…

知识图谱系列3:读论文-《中国鸟类领域知识图谱构建与应用研究》-面向知识图谱的智能服务研究(需求、管理、查询、推理)

5.1鸟类领域知识服务需求研究 本部分根据不同人群&#xff0c;对其需求进行了研究。 并总结需求类型如下。 知识型服务需求指用户学习鸟类相关知识&#xff0c;包括知识内容、知识学习等。知识内容 需求为构建鸟类领域知识库作为知识的来源&#xff1b;知识学习需求为用户通过…

gici-open示例数据运行(ground_truth坐标的转换)

1. 坐标系转换说明 涉及的两个坐标转换&#xff1a; nmea_pose_to_pose &#xff1a;激光IMU中心到数据集IMU中心&#xff0c;主要是杆臂误差&#xff0c;转换关系为&#xff1a; //坐标转换的主要步骤(若发现有错误的地方&#xff0c;请评论指出) //定义激光IMU和数据集IMU之…

好看的机制示意图绘制教程汇总

好看的机制示意图绘制教程汇总 蛋白翻译过程示意图&#xff0c;特别是其中的核糖体&#xff0c;需要很多绘制技巧。主要使用椭圆工具绘制两个椭圆&#xff0c;二者组合后使外形接近核糖体。接着通过路径查找器的合并功能&#xff08;并集&#xff09;将两个椭圆合并在一起。使…

使用HHDBCS管理MongoDB

1 连接MongoDB 打开HHDBCS&#xff0c;在数据库类型中选择mongodb&#xff0c;填入相关信息&#xff0c;点击“登陆”即可。 也可以使用SSH通道进行登陆。 2 命令窗口 点击命令窗口&#xff0c;可以对数据库发出指令。 可以根据个人习惯&#xff0c;对命令窗口进行设置…

矩阵的相似性度量的常用方法

矩阵的相似性度量的常用方法 1&#xff0c;欧氏距离 欧式距离是最易于理解的一种距离计算方法&#xff0c;源自欧式空间中两点间的距离公式。 (1)二维平面上的点 a ( x 1 , y 1 ) a(x_1,y_1) a(x1​,y1​)和点 b ( x 2 , y 2 ) b(x_2,y_2) b(x2​,y2​)的欧式距离为 d ( x …

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()…

旅游网站HTML

代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>旅游网</title> </head> <body><!--采用table编辑--> <!--最晚曾table,用于整个页面那布局--><table width&q…

Linux Ftrace介绍

文章目录 一、简介二、内核函数调用跟踪参考链接&#xff1a; 一、简介 Ftrace 是 Linux 官方提供的跟踪工具&#xff0c;在 Linux 2.6.27 版本中引入。Ftrace 可在不引入任何前端工具的情况下使用&#xff0c;让其可以适合在任何系统环境中使用。 Ftrace 可用来快速排查以下相…

0基础学习VR全景平台篇 第105篇:调色原理和色彩分析

“我心藏瑰宝灿烂如歌&#xff0c;唯有画作可为我吟唱。” 绘画、摄影、音乐等一切艺术&#xff0c;皆如是&#xff0c;敬梵高。 本节教程邀请李小岩老师讲授&#xff0c;大家欢迎&#xff01; 大家好&#xff01;欢迎收看我们这一节的课程&#xff0c;我们这一节呢主要讲的是…

川西旅游网系统-前后端分离(前台vue 后台element UI,后端servlet)

前台&#xff1a;tour_forword: 川西旅游网前端----前台 (gitee.com) 后台&#xff1a;tour_back: 川西旅游网-------后台 (gitee.com) 后端 &#xff1a;tour: 川西旅游网------后端 (gitee.com)

python对excel数据表进行数据清洗

当拿到excel表&#xff0c;使用python对excel操作前&#xff0c;第一件事情是对excel表的数据进行数据清洗。 数值是否有空值&#xff0c;是否有重复的数据&#xff0c;把以上2个问题解决完成以后&#xff0c;才是对数据真正操作的开始。 1、使用pandans读取数据 2、判断exce…

基于Springboot实现房屋租赁租房平台系统项目【项目源码+论文说明】分享

基于Springboot实现房屋租赁租房平台系统演示 摘要 在网络高速发展的时代&#xff0c;众多的软件被开发出来&#xff0c;给用户带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;房东只能以用户为导向&#xff0c;所以开发租房网…

RabbitMQ中basic**方法汇总与参数解释

当使用RabbitMQ进行消息传递时&#xff0c;Channel对象提供了一组称为"basic方法"的方法&#xff0c;用于执行最基本的消息传递操作。在本篇博客中&#xff0c;我们将详细介绍这些方法&#xff0c;包括示例和参数解释。 1. basicPublish 方法 basicPublish 方法用于…

商业智能系统的主要功能包括数据仓库、数据ETL、数据统计输出、分析功能

ETL服务内容包含&#xff1a; 数据迁移数据合并数据同步数据交换数据联邦数据仓库

C#WPF使转换器Converter使用实例

一、概述 Binding机制给程序的开发带来极大方便,但有时源数据和绑定对象之间需要进行一定的逻辑转换,直接的简单绑定不能满足使用要求,WPF当然考虑了这一点,在Binding中我们可以添加自定义的转换逻辑,即转换器Converter。WPF中的转换器是一个非常好的数据类型转换解决方案…

程序员之友:注释的重要性与最佳实践(InsCode AI 创作助手)

文章目录 1. 为什么程序员不写注释&#xff1f;1.1 时间压力1.2 自信过高1.3 懒惰1.4 认为代码足够简单1.5 不清楚注释的价值1.6 担心注释过多1.7 不懂如何写好的注释 2. 注释的重要性2.1 代码解释和文档化2.2 错误预防2.3 提高团队协作2.4 代码维护 3. 如何写出漂亮的注释3.1 …

c++面试题汇总(不定期更新...)

文章目录 0 引言1 c基础1.1 c和c的区别1.2 结构体struct和类class的区别1.3 结构体struct和共同体union的区别1.4 c指针pointer和引用reference的区别1.5 c中new和delete是如何实现的1.6 c中#define和const的区别1.7 c中关键字static的作用1.8 堆Heap和栈Stack的区别1.9 定义De…