第4章 伪指令(2016年3月3日)
单片机伪指令详解
伪指令依照其用途可分为五类:定义类、存储类、存储定义类、条件类及汇编方式类。
它们的具体分类及用途详见伪指令的类别一览类别a定义类用于对以下内容进行定义的伪指令:1.程序;2.程序中所用数据的性质、范围或结构;3.宏或结构4.程序5.其它1CODE、DATA、TEXT2IRAM、ISRAM、ORAM、OSRAM、RAM、SRAM3MACRO、MACEXIT、ENDM4PROC、ENDP、STRUCT、ENDS;5.DEFINE、VAR、PUBLIC、EXTERNAL、EQU、VDEFb存储类以指定的数据类型存储数据或设定程序地址等DW、DD、FLOAT、DOUBLE、ENDc存储定义类定义若干指定数据类型的数据存储单元DUPd条件类对汇编指令进行条件汇编IF、ELSE、ENDIF;IFMA、IFDEF、IFNDEFe汇编方式类包含汇编文件或创建用户定义段INCLUDE;SECTION详解:定义类伪指令DEFINE【类别】定义类【功能描述】定义常量符号【语法格式】.DEFINE variable[value][,…]【应用解释】给常量符号所赋之值既可是一已定义过的常量符号,亦可是一表达式。
切忌符号超前引用,即如果赋值引用的符号不是在引用前定义的,则会出现“非法超前引用”的错误。
【举例】.DEFINE BODY1;.DEFINE IO_PORT0x7016;.IFDEF BODY;R1=0xFFFF;[IO_PORT]=R1;.ENDIFPUBLIC【类别】定义类【功能描述】声明将被引用在其它文件中的全局标号【语法格式】.PUBLIC label[,label][,…]【应用解释】本伪指令用来在文件中声明将被引用在外部文件中的全局标号。
故在外部文件中用伪指令EXTERNAL所声明的标号必须是用PUBLIC伪指令声明过的。
类似地,当要声明多个全局标号时,要用逗号(,)将每一标号分开。
【举例】.PUBLIC sym1//声明要引用在其它文件中的全局标号.PUBLIC sym1,sym2//声明多个全局标号需用逗号将每一标号分开,空格会被忽略。
伪指令
南京航空航天大学信息科学与技术学院 石燕
DCW ( DCWU )
语法格式: 语法格式: 标号 DCW (或 DCWU ) 表达式 DCW (或 DCWU)伪指令用于分配一片连续的 ) 半字存储单元并用伪指令中指定的表达式初始化。 半字存储单元并用伪指令中指定的表达式初始化。 其中,表达式可以为程序标号或数字表达式。 其中,表达式可以为程序标号或数字表达式。 分配的字存储单元是半字对齐的, 用 DCW 分配的字存储单元是半字对齐的,而用 DCWU分配的字存储单元并不严格半字对齐。 分配的字存储单元并不严格半字对齐。 分配的字存储单元并不严格半字对齐 使用示例: 使用示例: DataTest DCW 1 , 2 , 3 分配一片连续的半字存储单元并初始化。 分配一片连续的半字存储单元并初始化。
南京航空航天大学信息科学与技术学院 石燕
SPACE
语法格式: 语法格式: 标号 SPACE 表达式 SPACE 伪指令用于分配一片连续的存储区域 并初始化为 0。其中,表达式为要分配的字节 。其中, 数。 代替。 也可用 “ % ” 代替。 使用示例: 使用示例: DataSpace SPACE 100 分配连续 100 字节的存储单元并初始化为 0
南京航空航天大学信息科学与技术学院 石燕
SETA 、 SETL 、 SETS
语法格式: 语法格式: 变量名 SETA ( SETL 或 SETS ) 表达式 伪指令 SETA 、 SETL 、 SETS用于给一 用于给一 个已经定义的全局变量或局部变量赋值。 个已经定义的全局变量或局部变量赋值。 SETA 伪指令用于给一个数学变量赋值 SETL 伪指令用于给一个逻辑变量赋值 SETS 伪指令用于给一个字符串变量赋值
南京航空航天大学信息科学与技术学院 石燕
伪指令和汇编语言
从指定单元开始,定义若干个字(双字节数)。
例如:
ORG 8000H
HETAB:
DW 7234H,8AH,10
汇编后则:
(8000H)=72H (8001H)=34H (8002H)=00H (8003H)=8AH (8004H)=00H (8005H)=0AH
03 常用旳伪指令
DS:定义空间命令
“DS <体现式>定义空间命令 格式: 标号: DS 数据或字符体现式 从指定单元开始,由数据或体现式 拟定保存若干个字节内存空间备用。 例如: ORG 8000H DS 08H DB 30H,8AH 即8000H~8007H单元保存备用 (8008H)=30H (8009H)=8AH
DATA和EQU旳区别在于DATA定义旳字符名称
作为标号登记在符号表中,故可先使用后定义;
而用EQU定义旳字符名称必须先定义后使用,其
原因是EQU不定义在符号表中。
03 常用旳伪指令
BIT:位地址符号命令
“
BIT<体现式>位地址符号命令
格式:
字符名称:
BIT 位地址
该命令把地址赋予标号段要求旳字符名称。
地址,位地址或立即数。
例如:
ORG 8000H
AA: EQU R6
;AA与R6等值
MOV A,AA
;A(R6)
…
03 常用旳伪指令
DATA:数据地址赋值命令
“ DATA<体现式>数据地址赋值命令 格式:
字符名称:
DATA 数据或体现式
此命令把数据地址或代码地址赋予标号段要求旳字符名称。
例如:INDEXJ DATA 8389H
定义了INDEXJ这个字符名称旳地址为8389H,主要用于
8086汇编语言伪指令
一、伪指令详解伪指令在百度百科中的定义为:伪指令(Pseudo Instruction)是用于对汇编过程进行控制的指令,该类指令并不是可执行指令,没有机器代码,只用于汇编过程中为汇编程序提供汇编信息。
例如,提供如下信息:哪些是指令、哪些是数据及数据的字长、程序的起始地址和结束地址等。
伪指令有2个特点:1.由于是伪“指令”,因而它只存在于汇编语言中。
高级语言中不叫指令,叫语句;2.由于是“伪”指令,也即“假”指令,因而不是可执行指令,不会产生机器代码,不会占用ROM空间,只用于汇编过程中为汇编程序提供汇编信息。
与指令的区别::1.指令是在执行阶段发挥作用的,由CPU(Intel、AMD等)来执行。
2.伪指令是在编译阶段发挥作用的,由汇编器(MASM、TASM等)来解释。
二、数据定义伪指令为源程序中的数据和堆栈区分配数据存储单时,使用最多的伪指令。
数据定义伪指令格式如下:常用的数据定义伪指令类型有:∙DB(定义字节,常用)一个字节数据占1个字节单元,读完一个,偏移量加1∙DW(定义字,常用)一个字数据占2个字节单元,读完一个,偏移量加2∙DD(定义双字)一个双字数据占4个字节单元,读完一个,偏移量加4∙DQ(定义四字)一个四字数据占8个字节单元,读完一个,偏移量加8∙DT(定义十字节,用于BCD码)数据定义伪指令后面的初值表可以是常数、表达式、字符串。
例如:D2DW110*230;为D2分配1个字,存放表达式的值D3DB‘GOOD!’;为D3分配5字节,用来存放字符串‘GOOD!’D4DD2.4E+3;为D4分配2个字,存放一个浮点数D5DB‘AB’;为D5分配2字节,字符A在低字节,B在高字节D6DW‘AB’;为D6分配1个字,字符A在高字节,B在低字节S1DB5DUP(?);为S1预留5字节的存储空间S2DW3DUP(0);为S2分配3个字,初值设为0语句1相当于C语言中的DW D2=110*230,只不过是语法结构不太一样注意:通过变量名操作时,变量名代表存储区的第一个数据的地址。
第四章 汇编语言程序设计
二、程序设计
1.程序设计步骤
① 分析问题
②分配内存单元 ③ 确定算法 ④画出程序流程图 ⑤ 编写汇编语言源程序 ⑥ 汇编语言程序的调试
2.程序流程图
关于流程图符号: 开始、结束----圆角矩形 工作任务----矩形 判断分支----菱形 程序流向---程序连接----
为选择结构。 该结构中包含 一个判断框 , 根据给定条件 P 是否成立而选择执行 A 框操作 或B 框操作。 条件P 可以是累 加器是否为零、 两数是否相 等 , 以及测试状态标志或位 状态等等。
例1:比较两个无符号数的大
小。 设外部 RAM 的存储单元ST1 和ST2中存放两个不带符号的 二进制数, 找出其中的大数 存入外部 RAM 中的ST3单元 中。
6.预留存储空间伪指令DS 格式: [标号: ]DS 表达式 该伪指令的功能是从标号指定的单元开始 , 保留若干字节
的内存空间以备使用。 存储空间内预留的存储单元数由表达式的 值决定。 例如: ORG 1000H DS 20H DB 30H, 8FH 汇编后: 从 1000H开始, 预留 32(20H)个字节的内存单元 , 然后 从 1020H 开 始 , 按 照 下 一 条 DB 指 令 赋 值 , 即 (1020H)=30H, (1021H)=8FH。 保留的存储空间将由程序的其它部分决定它们的 用处。
汇编以后:(1000H)=38H,
5.定义字指令DW
指令格式:
[标号:] DW 16 位数据表 该指令的功能与DB相似, 区别仅在于从指定地址开始存放 的是指令中的 16 位数据。每个 16 位数据要占两个存储单元, 高8 位先存, 低 8 位后存 例如: ORG 1500H TAB2: DW 1234H,80H 汇 编 以 后 :(1500H)=12H,(1501H)=34H, (1502H)=00H, (1503H)=80H。
指令、伪指令、伪操作的概念及其作用。
指令、伪指令、伪操作的概念及其作用。
指令、伪指令和伪操作是计算机操作中的重要概念,它们在程序的开发和执行过程中起到了关键作用。
指令(Instruction)是计算机程序中最基本的执行单位。
它是对计算机硬件发出的一个命令,指示计算机执行某种特定的操作。
在计算机的执行过程中,指令被送入处理器中进行解码和执行。
指令通常包括操作码和操作数两个部分。
操作码(Opcode)指明将要执行的操作的类型,操作数(Operand)则表示执行该操作需要的数据或操作的地址。
伪指令(Pseudoinstruction)是一类特殊的指令,它在高级语言编译器或汇编器中扮演了重要的角色。
伪指令看起来像是指令,但在硬件层面并不对应特定的操作。
伪指令主要用于控制程序的编译和链接过程,以及为程序员提供方便的程序设计功能。
它们和普通指令一样出现在源代码中,但在编译器的处理中会被转化为真正的指令或伪操作。
伪操作(Pseudo-operation),也称为汇编器指示符或汇编器伪指令,是在汇编语言中使用的一种特殊语法。
伪操作不是用来执行特定的计算或操作,而是在编译、链接、调试和优化等过程中对程序进行管理和控制的指令。
伪操作通常用于定义常量、申明变量、分配存储空间、定义代码的起点和终点等。
它们在编译过程中起到了更高层次的控制和调度作用,用于生成目标代码时提供相关指示。
举例来说,伪操作可以用于定义常量,如:```.DATAPI EQU 3.14159```上述代码将在目标代码的数据段中定义一个名为PI的常量,并将其值设置为3.14159。
另一个例子是用于声明变量并分配存储空间,如:```.DATACount DW 100```上述代码声明了一个名为Count的变量,并分配了一个字(16位)的存储空间。
伪操作还可以用于定义代码的起始点和终止点,如:```.CODESTART:......END:```上述代码定义了一个名为START的标签,表示程序的起始点;同时,定义了一个名为END的标签,表示程序的终止点。
伪指令注释
伪指令注释第一篇:伪指令注释汇编伪指令注释:1、DS ---预留存储区命令格式:〔标号:〕 DS 表达式值其功能是从指定地址开始,定义一个存储区,以备源程序使用。
存储区预留的存储单元数由表达式的值决定。
TMP: DS 1 从标号TEP 地址处开始保留1个存储单元(字节)。
2、BIT---定义位命令格式:字符名称 BIT 位地址其功能用于给字符名称定义位地址。
SPK BIT P3.7 经定义后,允许在指令中用SPK代替P3.7。
3、USING指令USING指令通知汇编器使用8051的哪一个工作寄存器组。
格式:USING 表达式(值必须为0-3,默认值为0。
)USING 0 使用第0组工作寄存器。
4、SEGMENT指令SEGMENT 指令用来声明一个再定位段和一个可选的再定位类型。
格式:再定位段名 SEGMENT 段类型〔再定位类型〕其中,“再定位段名”用于指明所声明的段。
“段类型”用于指定所声明的段将处的存储器地址空间。
可用的段类型有CODE、XDATA、DATA、IDATA和BIT。
STACK_SEG SEGMENT IDATA DATA_SEG SEGMENT DATA5、RSEG---再定位段选择指令再定位段选择指令为RSEG,用于选择一个已在前面定义过的再定位段作为当前段。
格式: RSEG 段名段名必须是在前面已经声明过的再定位段。
DATA_SEG SEGMENT DATA ;声明一个再定位DATA段RSEG DATA_SEG ;选择前面声明的再定位DATA段作为当前段6、绝对段选择指令CSEG---绝对代码段DSEG---内部绝对数据段 XSEG---外部绝对数据段ISEG ---内部间接寻址数据段BSEG---绝对位寻址数据段格式:CSEG [AT 绝对地址表达式] DSEG [AT 绝对地址表达式] XSEG [AT 绝对地址表达式] ISEG [AT 绝对地址表达式] BSEG [AT 绝对地址表达式] 括号内是可选项,用来指定当前绝对段的基地址。
第四章 伪指令
数据定义伪指令的格式为: [变量名] DB(DW、DD、DQ、DT) 表达式1,表达式2,… 表达式1,表达式2……是给变量或指定的存储单元赋予初值,它们有以下几种形式: (a)数值表达式 数据定义伪指令可以为一个或连续的存储单元设置数值初值。 (b)字符串表达式 对于DB伪指令,字符串的长度允许超过2个字符,但不能超过255个字符,字符 串必须用单引号括起来,它可为字符串中的每个字符分配1字节单元,字符串 从左至右以字符的ASCII码形式按地址递增的顺序依次存放。 (c)?表达式 不带引号的?,用于为变量预留内存单元,暂时不存入数据,即表示所定义的 变量无确定的初值。 例如:A DW ?,?为变量A预留2个字单元。 (d)地址表达式 操作数为地址表达式时,只适用于DW和DD这两种数据定义伪指令。如果地址表 达式为一变量(标号)名,用DW伪指令则是取它的偏移地址来初始化变量;用 DD伪指令则是取它的段首地址和偏移地址来初始化变量。 (e)带DUP的表达式 格式为:n DUP (表达式),其中n为重复因子,只能取正整数,它表示定义了 n个相同的数据存储单元。
在8086汇编语言中,运算符分为:算术运算符、逻辑运算符、关系运算
符、数值返回运算符、属性运算符和字节分离运算符。
(一)、表达式
(1)数值表达式 数值表达式是由常量与算术运算符、逻辑运算符或关系运算符构成的有意 义的式子。数值表达式在汇编期间进行运算,运算结果为一数值常量,它 只有大小而没有属性。
数据定义伪指令的格式为: [变量名] DB(DW、DD、DQ、DT)
Байду номын сангаас
表达式1,表达式2,„
其中:变量名是可选项,它仅代表所定义数据存储区第一个单元的地址; DB、DW、DD、DQ和DT是伪指令符,具体一条数据定义伪指令取5种之一。 DB定义的是字节类型的变量,每个表达式被分配1个字节单元。 DW定义的是字类型的变量,每一个表达式被分配1个字单元(2个字节)。 DD定义的是双字类型的变量,每一个表达式被分配2个字单元(4个字节)。 DQ定义的是四字类型的变量,每一个表达式被分配4个字单元(8个字节)。 DT定义的是十字节类型的变量,每一个表达式被分配10个字节单元。
汇编语言伪指令
汇编语言伪指令在汇编语言程序里,有一些特殊的助记符,这些助记符与指令系统的助记符不同,它们没有对应的机器码。
这些助记符在源程序中的作用是完成汇编程序的各种准备工作,包括定义变量、分配数据存储空间、控制汇编过程、定义程序入口等。
它们仅仅在汇编的过程中起作用,一旦汇编过程结束,它们的使命也就完成了。
这些助记符称为伪指令,它们所完成的操作称为伪操作。
不同汇编器的伪指令可能存在少量的区别,并非所有的伪指令在任何编译器上都能被识别。
一、符号定义伪指令符号定义(Symbol Definition)伪指令用于定义ARM汇编程序中的变量,对变量赋值和定义寄存器别名等,如表1所列。
表1 符号定义伪指令实例:GBLL P_ON ; 定义全局逻辑变量P_ON P_ON SETL {TRUE} ; 给全局逻辑变量P_ON赋值为真LCLA NUM ; 定义局部数字变量NUM NUM SETA 100 ; 给全局数字变量NUM赋值为100RegList RLIST {R0-R5,R8,R10} ; 定义一个寄存器列表RegList,可用微处理器系统结构与嵌入式系统设计(第3版)2; LDM/STM指令访问该列表二、数据定义伪指令数据定义(Data Denfinition)伪指令一般用于为特定的数据分配存储单元,同时完成对已分配存储单元的初始化工作。
数据定义伪指令如表2所示。
表2 数据定义伪指令从使用方法上来讲,数据定义伪指令可以分为以下3类。
1.SPACE伪指令SPACE用于分配一片连续的存储区,并初始化为0。
其中表达式中的数字表示分配的字节数。
SPACE也可以用%代替。
实例:DataSpace SPACE 100 ; 分配连续100字节的存储单元并初始化为0 2.MAP和FIELD伪指令MAP和伪指令FIELD经常结合在一起使用。
MAP用于定义一个结构化的内存表的首地址,可以用“^”替代。
FIELD用于定义一个结构化的内存表中的数据域,可以用“#”代替。
第四章伪指令
第四章伪指令汇编语言源程序由一系列语句构成,这些语句既可以是指令,也可以是伪指令。
指令是由CPU负责执行的,每一条指令都和一条机器语言相对应。
而伪指令是由汇编程序负责执行,完成一些内存单元分配、段之间的连接关系等操作,所以伪指令并不会生成机器指令,也就不会被CPU执行。
在本章中,重点讲解一些常用的伪指令及其功能。
4.1伪指令的分类及伪指令语句格式伪指令又称为伪操作,它虽然不会被CPU执行,但却可以指示汇编程序按照用户的意图,完成数据的定义、存储器的分配、指示程序结束等功能。
所以伪指令在汇编语言程序设计过程中具有重要的意义,希望读者在学习过程中应该加以高度重视。
4.1.1 伪指令的分类8088/8086的伪指令大致可分为以下八类:·数据定义伪指令;·符号定义伪指令;·段定义伪指令;·过程定义伪指令;·结束伪指令;·条件汇编伪指令;·结构、记录定义伪指令;·其他伪指令。
其中,条件汇编伪指令与结构、记录定义伪指令将在第八章予以介绍。
4.1.2 伪指令语句格式伪指令语句格式一般由四部分组成。
语句格式: [变量] 伪指令助记符参数1,参数2····参数n[;注释]说明:伪指令助记符规定了伪指令的功能。
一般伪指令都有参数,用于说明伪指令的操作对象,参数的类型和个数随着伪指令的不同而不同。
有时参数是常数或数值表达式,有时参数是一般的符号,有时是具有特殊意义的符号。
伪指令语句中的变量可有可无,如果伪指令语句中出现变量,则汇编程序使其记以第一个字节的偏移地址。
注释部分也是可有可无的,用于说明该伪指令的功能。
例如 VAR1 DW 1234H,5678H ;定义VAR1为字变量该语句中的VAR1为变量;DW为伪指令助记符;1234H与5678H为参数;分号后面给出的文字为注释。
4.2汇编语言中的数据项数据项是指令或伪指令语句操作对象的基本组成部分。
第4章 GNU汇编伪指令集
• 8.重复 • 作用:重复执行后面的命令 • 格式:
– .rept count commands .endr
重复次数
命令序列
.rept 3 .long 0 .endr
.long 0 .long 0 .long 0
陈付龙:嵌入式系统
21
4.1.4 汇编控制伪操作
• 控制汇编程序的执行流程
陈付龙:嵌入式系统
– Symbol .equ expr
start .equ 0x40 start .equ 0x50 mov r1, #start r1
0据定义伪指令
• 为特定的数据分配存储单元 • 初始化存储单元
陈付龙:嵌入式系统
13
• 1.字节分配
• 作用:在存储器中分配一个字节,用指定 的数据对其初始化 • 格式:
– 汇编控制伪操作
• if, else, endif, macro, endm, exitm
– 杂项伪操作
• align, section, data, text, include, arm, code, thumb, weak, end
–…
陈付龙:嵌入式系统
7
4.1.2 符号定义伪指令
• 定义全局变量或局部变量 • 给全局变量或局部变量赋值
陈付龙:嵌入式系统
4
4.1.1 伪指令概念
• 在ARM汇编语言程序中,有一些特殊指令助记符, 这些助记符与指令系统的助记符不同,没有相对应 的操作码,通常称这些特殊指令助记符为伪操作标 识符(directive),它们所完成的操作称为伪操作。 • 它既不控制机器的操作也不被汇编成机器代码,只 能为汇编程序所识别并指导汇编如何进行。 将相对 于程序或相对于寄存器的地址载入寄存器中。 • 伪指令在源程序中的作用是为了完成汇编程序做各 种准备工作的,这些伪操作仅在汇编过程中起作用, 一旦汇编结束,伪操作的使命就完成。
第4章 伪指令与源程序格式汇总
第4章伪指令与源程序格式汇编语言程序的语句有三种,即指令、伪指令,还可以有宏指令。
关于宏指令将在第7章介绍,本章介绍部分常用的伪指令(又称伪操作)。
这些伪指令在程序中是必不可少的,主要用来定义数据变量和程序结构。
本章还介绍指令中的操作数和运算符,通过本章的学习,可以学会使用简便而有效率的指令格式,正确定义数据变量,熟知源程序的格式,编写完整的汇编语言程序。
4.1 伪指令伪指令和指令不同的是,指令是在程序运行期间由计算机的CPU来执行的,而伪指令是在汇编程序对源程序进行汇编期间由汇编程序处理的操作。
它们可以完成如定义数据、定义程序模式、分配存储区、指示程序结束、处理器选择等功能。
这里只介绍一些常用的伪指令。
有些和宏汇编有关的伪指令在介绍宏汇编时再作说明。
4.1.1 处理机选择伪指令由于80x86的所有处理器都支持8086指令系统,但每一种高档的机型又都增加了一些新的指令。
为了能使用这些新增指令,在编写程序时要用处理机选择伪指令对所用的处理机作出选择,也就是说,要告诉汇编程序应该选择哪一种指令系统。
处理机选择伪指令有以下几种:.8086 选择8086指令系统.286 选择8O286指令系统.286P 选择保护方式下的80286指令系统.386 选择80386指令系统.386P 选择保护方式下的8O386指令系统.486 选择80486指令系统.486P 选择保护方式下的8O486指令系统.586 选择Pentium指令系统.586P 选择保护方式下的Pentium指令系统指令中的点‘.’是需要的。
这类伪指令一般放在整个程序的最前面。
如不给出,则汇编程序认为其默认选择是8086指令系统。
4.1.2 段定义伪指令我们结合第2章已介绍的程序实例2来看段定义,注意有分号的注释行,程序如下:例4.1data segment ;定义数据段datastring db ‘hello,world!$’data endscode segment ;定义代码段codeassume cs:code,ds:data ;指定段寄存器和段的关系start:mov ax,data ;对ds赋data段基地址mov ds,axmov dx,offset stringmov ah,9int 21hmov ah,4chint 21hcode endsend start ;汇编结束, 程序起始点start:1.段定义伪指令汇编程序在把源程序转换为目标程序时,必须确定标号和变量(代码段和数据段的符号地址)的偏移地址,连接程序对针目标程序把不同的段和模块连接在一起,确定各个段的段地址。
第4章 ARM伪指令
用DCFS伪指令分配的字存储单元是字对齐的,而用DCFSU伪指 令分配的字存储单元并不严格要求字对齐。
(9)DCQ(或DCQU)伪指令
DCQ(或DCQU)伪指令用于分配一片以8字节为单位的连续存 储区域,并用伪指令中指定的表达式初始化。其语法格式如下。
4.3.2 定义寄存器列表伪指令
LDM/STM指令需要使用一个比较长的寄存器列表,使用伪指令 RLIST可对一个列表定义一个统一的名称。其格式如下。 <Name> RLIST <{List}>
4.3.3 数据定义伪指令
(1)LTORG伪指令 LTORG伪指令用来说明某个存储区域为一个用来暂存数据的数
<Label> DCQ(或DCQU) <Expr>
用DCQ伪指令分配的存储单元是字对齐的,而用DCQU分配的字 存储单元并不严格要求字对齐。
(10)DCW(或DCWU)伪指令
DCW(或DCWU)伪指令用于为数据分配一片连续的半字存储单 元,并用表达式对其进行初始化。
<Label> DCW(或DCWU) <Expr>
(1)近地址读取宏指令ADR ADR宏指令用于将一个近地址值传递到一个寄存器中,指令格
式如下。 ADR{Cond} <Reg>, <Expr> Reg为目标寄存器名称。 Expr为表达式。该表达式通常在一个程序中表示一条指令存储
位置的地址标号。
该宏指令的功能是把标号所表示的地址传递到目标寄存器中。 汇编器在汇编时,将把ADR宏指令替换成一条真正的ADD或SUB指令, 将当前的PC值减去或加上Expr与PC之间的偏移量得到标号的地址, 并将其传输到目标寄存器。
伪指令
四、伪指令(一)伪指令的介绍一般来说,在汇编语言源程序中用MCS-51指令助记符编写的程序,可以产生目标程序。
但还有一些指令并不产生目标程序,不影响目标程序的执行,仅产生供汇编用的某些命令,以便在汇编时执行一些特殊的操作,这种指令称为伪指令。
指令ORG位起始伪指令,它规定其下面的目标程序的起始地址。
指令中16位地址(4位十六进制数)便是起始地址。
ORG定义空间地址由小道大,且不能重叠。
如果空间地址有重叠,汇编将拒绝执行,并给相应的出错信息。
2.END指令格式:ENDEND位结束伪指令,表明汇编语言源程序的结束标志,汇编程序对该指令后面的内容将不再进行汇编。
如果源程序是主程序,则写标号,所写标号就是该主程序第一条指令的符号地址。
如果源程序是一般子程序,END之后不再写标号。
3.EQU指令格式:字符名称EQU 数据或汇编符号EQU为等值伪指令,是将数据或汇编符号赋予字符名称。
需注意的是在同一程序中,用EQU伪指令在赋值后,其字符名称的值在整个程序中不能再改变。
例某程序为:PPT EQU R0 ;PPT=R0MOV A,PPT ;A←PPT说明:将PPT等值于汇编符号R0,在伪指令中PPT可以代替R0来使用。
4.DB指令格式:<标号:>DB<项或项表>DB为定义字节指令,项或项表指所定义一个字节或用逗号分开的字符串。
汇编程序把DB指令中项或项表所指字符的内容(数据或AS CⅡ码)依次存入从标号开始的存储器单元。
5.DATA指令格式:字符名称DA TA 表达式DATA为数据地址赋值伪指令,其功能将数据地址赋给字符名称。
DA TA与EQU指令既相似又有区别:(1)EQU指令可以把一个汇编符号赋给一个字符名称,而DATA指令不能;(2)EQU指令应先定义后使用,而DA TA指令先使用后定义;(3)DATA指令能将一个表达式的值赋予一个字符名称;(4)DATA指令在程序中用来定义数据地址。
汇编学习笔记(4)-伪指令(MASM)
汇编学习笔记(4)-伪指令(MASM)前⾔ 编写汇编代码的时候会使⽤到两种语句,⼀种就是前⾯介绍的汇编指令⼜CPU提供功能⽀持,另⼀种呢叫做伪指令,伪指令是由汇编的编译器提供⽀持。
所以伪指令的运⾏结果都必须实在编译的时候就能确定的,下⾯介绍的就是伪指令了。
注意接下来介绍的伪指令都是基于MASM汇编编译器,⽐较常⽤的还有NASM 它的语法以后有机会介绍数值表达式 数值表达式不是汇编指令,表达式的值是在汇编代码的汇编过程中就由汇编编译器计算出结果⽽写到⼆进制程序中了,并不是在程序运⾏的过程中才计算的 (1) 常数表达式 常数就是直接的数字,直接写数字默认表⽰10进制数,也可以⽤符号指定为其他进制 D = ⼗进制 ; MOV AL, 1234D B = ⼆进制 ; MOV AL, 0101B H = ⼗六进制 ; MOV AL, 0FFFFH , 注意常数必须是数字开头不能是字母开头,如果16进制数第⼀个数字是字母的话就要补⼀个0在前⾯ Q = ⼋进制 ; MOV AL, 123Q 因为在程序中字母也是数字,所以其实也可以直接将字母或者字符串当成数字,⽐如 MOV AL, 'a' MOV AX,"ab" ; 双引号和单引号都是可以使⽤的 (2) 算数运算符 就是简单的正(+) 负(-) 加(+) 减(-) 乘(*) 除(/) 模(mod) mov ax, 100+200 mov ax, 100/2 (3) 关系运算符 等于(EQ) 不等(NE) ⼤于(GT) ⼩于(LT) ⼤于等于(GE) ⼩于等于(LE) 如果等式成⽴则实际的值为0FFFF就是补码表⽰的-1, 如果关系不成⽴那么结果就是0 mov ax, 123 gt 234 mov ax, 1234+5 lt 1235 (4) 逻辑运算 与(and) 或(or) ⾮(not) 异或(xor) 左位移(shl) 右位移(shr) mov ax, 1 shl 3 mov al, 3 and 47 (5) 其他操作符 HIGH LOW WIDTH MASK HIGH 表⽰取数据的⾼⼋位 LOW 表⽰取数据的低⼋位地址表达式 地址表达式所表⽰的是存储器操作数的地址。
3-4 伪指令语句
3.4.5 其它伪指令
1. NAME 或TITLE 伪指令 格式: NAME 模块名 格式: TITLE 标题 NAME用来为模块取名字。 TITLE伪指令指定每一页上打印的标题。
2. 源程序结束伪指令
格式: END 表达式 其中表达式是该程序中第一条可执行语句的标号, 可以省略。 如果一个程序中包含多个模块,那么只有主程序 模块中的END语句需要带表达式。
3.4.4 过程定义伪指令
格式: 过程名
PROC NEAR/FAR RET 过程名 ENDP 功能:用来定义过程,供其他程序调用
•过程名是过程的名称,供其他程序调用时使用, 不能省略; •过程名具有段地址、偏移地址和类型三个属性; •过程名的段地址和偏移地址是指过程中第一条语 句的段地址和偏移地址; •过程名的类型属性由格式中的类型指明,可以有 NEAR和FAR两种。缺省是NEAR类型; •PROC和ENDP必须具有相同的过程名称; •过程内部至少要设置一条返回指令(RET)作为 过程的出口。允许过程中设置多条返回指令,即 具有多个出口。
PAGE:页边界 XXXX XXXX XXXX 0000 0000B PARA:段边界 XXXX XXXX XXXX XXXX 0000B WORD:字边界 XXXX XXXX XXXX XXXX XXX0B BYTE:字节边界 XXXX XXXX XXXX XXXX XXXXB
3.4.3 段分配伪指令 格式: ASSUME 段寄存器:段名[,段寄存器:段名,…] 功能:该语句安排在代码段的开始,通知汇编程序, 某个段是以哪一个段寄存器为它的段地址寄存器。
例:
ASSUME CS:CODE,DS:DATA,ES:EXTRA、ASTACK分别以CS、 DS、ES、SS为它们的段寄存器,这4个逻辑段分别被定义 为代码段、数据段、附加数据段和堆栈段。
第4章 伪指令与源程序格式汇总
第4章伪指令与源程序格式汇编语言程序的语句有三种,即指令、伪指令,还可以有宏指令。
关于宏指令将在第7章介绍,本章介绍部分常用的伪指令(又称伪操作)。
这些伪指令在程序中是必不可少的,主要用来定义数据变量和程序结构。
本章还介绍指令中的操作数和运算符,通过本章的学习,可以学会使用简便而有效率的指令格式,正确定义数据变量,熟知源程序的格式,编写完整的汇编语言程序。
4.1 伪指令伪指令和指令不同的是,指令是在程序运行期间由计算机的CPU来执行的,而伪指令是在汇编程序对源程序进行汇编期间由汇编程序处理的操作。
它们可以完成如定义数据、定义程序模式、分配存储区、指示程序结束、处理器选择等功能。
这里只介绍一些常用的伪指令。
有些和宏汇编有关的伪指令在介绍宏汇编时再作说明。
4.1.1 处理机选择伪指令由于80x86的所有处理器都支持8086指令系统,但每一种高档的机型又都增加了一些新的指令。
为了能使用这些新增指令,在编写程序时要用处理机选择伪指令对所用的处理机作出选择,也就是说,要告诉汇编程序应该选择哪一种指令系统。
处理机选择伪指令有以下几种:.8086 选择8086指令系统.286 选择8O286指令系统.286P 选择保护方式下的80286指令系统.386 选择80386指令系统.386P 选择保护方式下的8O386指令系统.486 选择80486指令系统.486P 选择保护方式下的8O486指令系统.586 选择Pentium指令系统.586P 选择保护方式下的Pentium指令系统指令中的点‘.’是需要的。
这类伪指令一般放在整个程序的最前面。
如不给出,则汇编程序认为其默认选择是8086指令系统。
4.1.2 段定义伪指令我们结合第2章已介绍的程序实例2来看段定义,注意有分号的注释行,程序如下:例4.1data segment ;定义数据段datastring db ‘hello,world!$’data endscode segment ;定义代码段codeassume cs:code,ds:data ;指定段寄存器和段的关系start:mov ax,data ;对ds赋data段基地址mov ds,axmov dx,offset stringmov ah,9int 21hmov ah,4chint 21hcode endsend start ;汇编结束, 程序起始点start:1.段定义伪指令汇编程序在把源程序转换为目标程序时,必须确定标号和变量(代码段和数据段的符号地址)的偏移地址,连接程序对针目标程序把不同的段和模块连接在一起,确定各个段的段地址。
伪指令用来对汇编程序进行控制
伪指令用来对汇编程序进行控制,对程序中的数据实现条件转移、列表、存储空间分配等处理,其格式和汇编指令一样,但一般不产生目的代码,即不直接命令CPU 去执行什么操作。
伪指令是汇编语言的特色之一,具有两个基本特征:1、伪指令是一条指令。
它在程序中不是可有可无的,使用时受到严格的规范,与标准指令一样,在程序中占有固定的位置,有固定的书写格式。
每条伪指令都与标准指令一样可实现特定的功能,伪指令是不能用标准指令替代的。
2、伪指令不是一条真正的指令,没有指令代码。
在程序编译过程中,伪指令的功能会被实现,但伪指令会被删除,在编译后的目标文件中(目标文件一般是代码文件),不会有伪指令的编码。
也可以这样理解:指令是对计算机发出的命令,而伪指令则是对编译器发出的命令。
在编译程序结束时,伪指令的使命就完成了。
伪指令是相对标准指令而言的,高级语言不存在伪指令,因为高级语言不存在指令,很难说明高级语言中哪一条语句是什么指令。
伪指令是为程序开发工程师提供辅助的程序表达,让编译器实现一些标准指令所不能表达的内容。
伪指令的作用:1、程序定位的作用。
把各程序段之间的相互关系和在存储器的位置告诉编译器。
2、为非指令代码进行定义。
包括逻辑变量、字符和存储区等。
3、为程序完整性做标注。
程序段的开始和结束。
4、有条件地引用程序段。
比如条件循环、条件选择以及宏等。
在ARM处理器中,伪指令的应用和51系列的单片机很相似,它们除了把正常的程序用指令表达给计算机以外,还需要把程序设计者的意图表达给编译器。
无论是51系列单片机还是ARM处理器,都需要定义数据以便编译器能够正确识别代码和数据,都可以引用宏,都可以为符号或变量赋值等。
一、定义数据伪指令该类伪指令用来定义存储空间及其所存数据的长度。
· DB :定义字节,即每个数据是 1 个字节。
· DW :定义字,即每个数据占 1 个字 (2 个字节 ) 。
· DD :定义双字,即每个数据占 2 个字。
伪指令语句
运行,它往往是作为一个子模块供另外的程序调用。
(3)TYPE运算符:获取变量或标号的类型。
例: X1 X2 X3
DB DW DQ
STRING 4000H ?
MOV AL,TYPE X1 (AL) 1 MOV CL,TYPE X2 (CL) 2 MOV DL,TYPE X3 (DL) 8 (4)LENGTH 运算符:获取数组变量的长度。 限制:只用于非嵌套DUP操作符定义的数组变量。 例: CH1 DW 200 DUP (?) CH2 DB 1,2,3 CH3 DW 100 DUP (1,2,3,4 DUP(0)) CH4 DB length MOV CX,LENGTH CH1 (CX) 200 1 MOV AH, LENGTH CH2 (AH) 100 MOV CL,LENGTH CH3 (CL) 1 MOV CH, LENGTH CH4 (CH)
DUP 可嵌套: ARRAY2 DB 100 DUP ( 3,4,2 DUP (1,2),2 DUP( 0 ) ) 定义100组数据 :3,4,1,2,1,2,0,0
2)分析运算符— 获取变量或标号的属性 (1)SEG运算符:获取变量或标号的段地址
例:3150H:0100H XP DW 2000H:0400H ARRAY DW
ADDA
ADDAD
00 20 00 20 00 04
偏移地址 偏移地址 段地址
例3:定义5个字节单元,并都初始化为0 ARRAY DB 0, 0, 0, 0, 0 1) 复制操作符 格式: 表达式 DUP (初值表) ARRAY DB 100 DUP(0) 定义大量具有一定规律的数据: ARRAY1 DB 2 DUP(1,2,3) 定义的数据 :1 ,2 ,3 ,1 ,2,3
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在默认情况下,局部变量只在定 义该变量的 程序段内有效。
(3)变量赋值伪指令 SETA、SETL和SETS
伪指令 SETA、SETL和SETS 用于给 一个 已经定义 的 全局变量 或 局部变 量 进行赋值。 注:要顶格写
Test1 SETA 值为0xAA。
0xAA
共74页
;将Test1变量赋
注意:MAP 和 FIELD 伪指令仅用 于定义数据结构,并不实际分配存储单 元。 FIELD 也可用“#” 代替。
共74页 36
(3)SPACE SPACE 伪指令用于分配一片连续 的存储区域并初始化为 0。
<label> SPACE <expr>
表达式为要分配的 字节数, SPACE 也可用“%” 代替。 DataSpace SPACE 100 ;分配连续的 100字节的存储单元并初始化为 0。
共74页 12
ADRL{cond}
<reg>, <expr>
reg 为目标寄存器名称;
Expr 为表达式,必须是 64KB 以内非字 对齐地址,256KB 以内的字对齐地址。
该指令只能在 ARM 状态下使用,在 Thumb 状态下不能使用。汇编时,ADRL 宏指令由汇编器替换成 两条合适的指令。
共74页 13
共74页 33
MAP fun ; fun就是内存表的首地址 MAP 0x100,R9 ;内存表的首地址为R9+0X100
MAP 通常和 FIELD 伪指令相配合 来定义一个结构化的内存表。 FIELD 伪指令用于定义一个结构 化内存表中的数据域。 <label> FIELD
共74页
<expr>
34
4.3.3 数据定义伪指令 (8)LTORG
伪指令 LTORG 用来说明某个存储区 域为一个用来暂存数据的数据缓冲区, 也叫文字池或数据缓冲池。大的代码段 也可以使用多个数据缓冲池。
共74页
28
下图为 LTORG 的作用。
共74页
29
当程序中使用 LDR 之类的指令 访问数据缓冲池时,为防止越界发 生,通常把数据缓冲池放在代码段 的最后面,或放在无条件转移指令 或 子程序返回指令之后,这样处理 器就不会错误地将数据缓冲池中的 数据当作指令来执行。
在应用程序中经常使用一种如下图所 示的表:
共74页
32
MAP 可以用“^” 代替。 MAP 用于定义一个结构化的内存表 的首地址。语法格式如下:
MAP <expr> {,<baseregister>}
expr 为结构化表首地址。可以为 标 号 或 数字表达式。
baseregister 为基址寄存器(可选 项)。基址寄存器的值与 expr 的值之 和就是表首地址。
共74页
30
AREA example, CODE, READONLY Start BL Func1 … Func1 LDR R1,=0x800 MOV PC,LR LTORG ;定义数据缓冲池的开始位置 Date SPACE 40 ;数据缓冲池有40个被初 END ;始化为0的字节
共74页
31
(2)MAP 和 FIELD
GBLL 定义一个 全局逻辑变量 ,其 默认初值为 F(假);
GBLS 定义一个 全局字符串变量,其 默认初值为 空 ; GBLA Test1 ;定义一个全局数字 变量,变量名为 Test1 GBLL Test2 ;定义一个全局逻辑变 量,变量名为 Test2
共74页 21
GBLS Test3 ;定义一个全局字符 串变量,变量名为 Test3
共74页 18
4.3.1 为变量定义或赋值的伪指令 符号的命名由编程者决定,但必须 遵循以下约定:
(1)符号区分大小写,同名的大、小写 符号会被编译器认为是两个不同的符号; (2)符号在其作用范围内必须唯一;
(3)自定义的符号不能与系统保留字 相同; (4)符号不应与指令或伪指令同名。
共74页 19
label 为标号。
要顶格写
expr 为表达式。它的值为数据域所 占的字节数。
FIELD 伪指令与 MAP 伪指令配 合使用来定义结构化的内存表。 MAP 伪指令定义内存表的首地址; FIELD 伪指令定义内存表中各个数据域,并 可以为每个数据域指定一个 标号 供 其他指令引用。
共74页 35
MAP 0X100 ;定义结构化内存表首地址为 0X100 A FIELD 16 ;定义A的长度为16字节,位置为 0X100 B FIELD 32 ;定义B的长度为32字节,位置为 0X110 S FIELD 256 ;定义S的长度为256字节,位置为 0X130
共74页 3
2、伪指令具有的两个特征 (1)伪指令是一条指令;
(2)伪指令没有指令代码。
3、伪指令的作用 (1)程序定位的作用; (2)为非指令代码进行定义; (3)为程序完整性做标注; (4)有条件的引导程序段。
共74页 4
4.2
4.2.1 宏
与ARM指令相关的宏指令
(1)MACRO 和 MEND MACRO 和 MEND 宏指令可以为一个 程序段定义一个名称。这样,在汇编语 言应用程序中就通过这个名称来使用它 所代表的程序段,即当程序做汇编时, 该名称将被替换为其所代表的程序段。
start
MOV R0,#10 ADRL R4,start + 60000
其中 ADRL 将被替换为如下两条指令: ADD R4,PC,#0XE800 ADD R4,R4,#0X254 如果汇编器找不到合适的两条指 令,将会报错。
共74页 14
(3)全范围地址读取宏指令 LDR
LDR{cond} reg,={expr | label - expr}
共74页 10
共74页
11
由于指令 ADD 或 SUB 中对 立即数的 限制,因此标号地址就不能距离当前指令 的地址(PC)过远。对于非字对齐地址来 说,其距离必须在 255 字节以内;而对于 字对齐地址来说,距离必须在 1020 字以 内。所以 ADR 叫做 近地址 读取指令。
(2)远地址读取宏指令 ADRL 类似于 ADR,但可以把 更远的地址 赋给目标寄存器。
25
Test2 SETL {TRUE} 量赋值为真。
;将 Test2 变
Test3 SETS “Testing” ;将 Test3 变量赋值为“Testing” 。 Test4 SETA 0xBB 赋值为0xBB。 Test5 SETL {TRUE} 赋值为真。
共74页
;将 Test4 变量 ;将 Test5 变量
共74页 5
MACRO $标号 宏名 $参数1, $参数2,….. 程序段(宏定义体) MEND $标号:为主标号,宏内的所有其它标号 必须由主标号组成; 宏名:宏名称,为宏在程序中的引用名; $参数1,$参数2:宏中可以使用的参数。
共74页 6
宏中的所有标号必须在前面冠以符 号“$”。
MACRO ;宏定义指令 $MDATA MAXNUM $NUM1,$NUM2 ;主标号,宏名,参数 语句段 $MDATD.MAY1 ; 宏内标号 语句段 $MDATA.MAY2 ; 宏内标号 语句段 MEND ; 宏结束指令
(1)声明全局变量伪指令 GBLA、GBLL和GBLS
GBLA、GBLL 和 GBLS 伪指令用于 定义一个ARM程序中的 全局变量,并 将其初始化。 GBLA(GBLL和GBLS) <variable>
variable 为变量名称; GBLA 定义一个 全局数字变量,其默认 初值为 0 ;
共74页 20
26
Test6 SETS “Testing” ;将 Test6变量赋值为“Testing” 。 4.3.2 定义寄存器列表伪指令 指令 LDM/STM 需要使用一个比较长 的寄存器列表,使用伪指令 RLIST 可对 一个列表定义一个统一的名称。 <name> RLIST
共74页
<{list}>
27
共74页 37
(4)DCB DCB 伪指令用于分配一片连续的 以 字节为单位 的存储区域,并用指定的表 达式对其进行初始化。 {<label>} DCB <expr> Label 为标号,为存储区域的首地址 (可选)。 Expr 为表达式,为从标号开始存放的数 据。该表达式可以为 0~255 的数字或字 符串。
共74页 7
(2)MEXIT
MEXIT 用于从宏定义中跳转出去。 MEXIT 4.2.2 宏指令 在ARM中,还有一种汇编器内置的 无参数和标号宏——宏指令。 在汇编时,这些宏指令被替换成一 条或两条 真正的 ARM 或 Thumb 指令。
共74页 8
(1)近地址读取宏指令 ADR
ADR 指令用于将一个 近地址值 传递到一个寄存器中。
共74页 16
由于这种指令可以传递一个 32 位地 址,因此被叫做 全范围地址读取指令。 (4)NOP 汇编器对 NOP 指令进行汇编时, 会将其转换为: MOV R0,R0
共74页 17
4.3
通用伪指令
在 ARM 汇编程序语言中,有 如下 几种 伪指令: 段定义、符号定义、数据定义、 数据缓冲池定义、数据表定义、数 据空间分配、汇编控制伪指令 以及 其他伪指令。
第 4章
伪指令
2学时
本章主要内容 1、伪指令概述; 2、与ARM指令相关的宏指令; 3、通用伪指令。
共74页 1
本章教学要求
掌握:ARM 的伪指令、宏。 目前汇编有 ARM ASM 汇编和 GNU ASM 汇编,本课程主要讲 ARM ASM 汇编。
共74页 2
4.1