汇编常见伪指令

汇编常见伪指令 

 转自: http://blog.chinaunix.net/uid-20547722-id-1647296.html

一、与宏有关的伪指令
在宏定义时,为了满足某种特殊需要,汇编语言还提供了几个伪指令。 
9.3.1 局部标号伪指令LOCAL 
在宏定义体中,如果存在标号,则该标号要用伪指令LOCAL说明为局部标号,否则,当在源程序中,有多于一次引用该宏时,汇编程序在进行宏扩展后将会给出:标号重复定义的错误。 
伪指令LOCAL的一般格式如下: 
LOCAL 标号1, 标号2, …… 
伪指令LOCAL必须是伪指令MACRO后的第一条语句,并且在MACRO和LOCAL之间也不允许有注释和分号标志。 
汇编程序在每次进行宏扩展时,总是把由LOCAL说明的标号用一个唯一的符号(从??0000到??FFFF)来代替,从而避免标号重定义的错误。 
例9.7 编写求一个求绝对值的宏。 
解: 
方法1: 
ABSMACROword1 
CMPword1, 0 
JGEnext 
NEGword1 
next: 
ENDM 

假设对宏ABS有以下两次引用,点击它们将会显示汇编程序对它们进行宏扩展后所得到程序片段: 
    ABS  BX  
  1     CMP BX, 0 
  1     JGE  next 
  1     NEG BX 
  1 next: 
… 
    ABS  AL  
  1     CMP AL, 0 
  1     JGE  next 
  1     NEG AL 
  1 next: 

在上述程序片段中,显然标号next定义了二次,所以,汇编程序将显示“标号重复定义”的错误信息。为了避免这种情况的发生,我们需要用下面的方法来定义该宏。 
方法2: 
ABSMACROword1 
LOCALnext 
CMPword1, 0 
JGEnext 
NEGword1 
next: 
ENDM 

假设对宏ABS有以下两次引用,点击它们将会显示汇编程序对它们进行宏扩展时所得到程序片段: 
    ABS  BX  
  1      CMP BX, 0 
  1      JGE  ??0000 
  1      NEG BX 
  1 ??0000: 
… 
    ABS  AL  
  1      CMP AL, 0 
  1      JGE ??0001 
  1      NEG AL 
  1 ??0001: 

在上述程序片段中,宏体内部的局部标号next分别用符号??0000和??0001来对应它的二次引用。因此,汇编程序不会再显示“标号重复定义”的错误信息。 
伪指令LOCAL在子程序中也可起作用(参见7.5.10节),但它的作用与宏定义的作用是不同的,有关该伪指令在子程序的宏定义中功能的主要差异如表9.1所列。 
表9.1 伪指令LOCAL在子程序和宏中的比较 
在子程序中在宏定义中 
语句的位置在所有指令之前在所有指令之前 
伪指令的作用说明局部变量说明局部标号 
伪指令的格式可用一条伪指令来说明多个局部变量,也可连续用多条伪指令来说明可用一条伪指令来说明多个局部标号,也可连续用多条伪指令来说明 
调用或引用子程序的不同调用,其局部变量名保存不变在每次宏引用的扩展时,将会自动产生出一个唯一的局部标号
二、取消宏定义伪指令
伪指令PURGE的一般格式如下: 
PURGE 宏名1, 宏名2, …… 
该伪指令通知汇编程序取消“宏名1, 宏名2, ……”宏名表中的宏定义。在此语句后,如果还有这些宏的引用语句,则汇编程序不会把它们当作宏引用来进行扩展,并且还将显示出错信息。 
伪指令PURGE的使用频率较低。 
9.3.3 中止宏扩展伪指令 
伪指令EXITM的一般格式如下: 
EXITM 
该伪指令书写在宏定义体中,用来告诉汇编程序:如果遇到该伪指令,那么,立即中止对该伪指令之下语句的扩展。如果在嵌套的内层宏中遇到了该伪指令,则退出到宏嵌套的外层。 
在一般情况下,伪指令EXITM与条件伪指令一起使用,以便在不同的条件下挑选出不同的语句。 
伪指令EXITM的使用频率也很低。
三、重复汇编伪指令
在编写源程序时,有时会出现连续相同或相似的语句(组)。当出现这种情况时,可利用重复伪指令来重复语句,从而达到简化程序的目的。 
重复汇编伪指令所定义的重复块是宏的一种特殊形式,也是由伪指令ENDM来结束重复块。用重复汇编伪指令定义的重复块也可带有参数,并在汇编过程中参数被实参代替,但重复块不会被命名,不能在程序的其它地方引用。 
9.4.1 伪指令REPT 
伪指令REPT的作用是把一组语句重复指定的次数,该重复次数由伪指令后面的数值表达式来确定。其一般使用格式如下: 
REPT数值表达式 
重复的语句组 
ENDM 

例9.8 定义100个初值为32的字节单元,该存储单元的起始符号地址为Table。 
解:  
方法1:用伪指令REPT来实现左边重复块的汇编结果如下:  
Table LABEL TYPE Table LABEL TYPE 
REPT 100 DB 32 
DB 32 … 
ENDM DB 32    ;上述字节定义重复100次 

方法2:用重复操作符DUP来实现 
Table DB 100 DUP(32) 
从上例来看,用伪指令REPT重复定义的存储单元可以用重复操作符DUP来代替,其实前者的功能会更灵活、更强大。 
例9.9 定义100个初值分别为1,2,…,100的字节单元,该存储单元的起始符号地址为Table。 
解:  
Table LABEL TYPE 左边重复块的汇编结果相当于:  
COUNT = 1 Table LABEL TYPE  
REPT 100 DB 1  
DB COUNT DB 2  
COUNT = COUNT + 1 …  
ENDM DB 100  

上面定义了100个字节,其初值为1,2,…,100。本例好象不能用重复操作符DUP来说明字节存储单元。 
例9.10 计算1+2+…+1000,并把其值存入寄存器AX。 
解:  
方法1:用伪指令REPT来实现左边重复块的汇编结果与下面程序段相一致:  
… …  
MOV AX, 0 MOV AX, 0  
COUNT = 1 ADD AX, 1  
REPT 1000 ADD AX, 2  
ADD AX, COUNT …  
COUNT = COUNT + 1 ADD AX, 1000  ;把AX从1累加到1000  
ENDM …  
… 虽然上面这些语句的执行能完成本例所指定的功能,但它是用1000条加法指令来直接计算的,这1000条指令无疑会大大增加目标代码的长度。 
方法2:用循环指令LOOP来实现 
… 
MOVAX, 0 
MOVCX, 1000 
again:ADDAX, CX 
LOOPagain 
… 

由例9.10,不难看出:伪指令REPT与循环指令起作用的时期和方式是截然不同的。它们之间的主要差异如表9.1所列。 
表9.1 伪指令REPT与循环指令LOOP之间的主要差异 
 伪指令REPT循环指令LOOP 
起作用的时期汇编程序把源文件翻译成目标文件时期程序的执行时期 
起作用的方式把被重复的指令(组)直接重复写入目标文件通过反复执行同一指令(组)来实现重复 
重复次数对目标文件的影响由于重复次数决定着被重复指令(组)写入目标文件的次数,所以,改变重复次数一定会改变目标文件的字节数由于重复的指令数与重复次数无关,所以,改变重复次数不会改变目标文件的字节数
四、重复汇编伪指令 伪指令IRP
伪指令IRP 
伪指令IRP的作用是用每个参数创建一组语句,其重复次数由伪指令后面参数表中参数的个数来确定。其一般使用格式如下: 
IRP形式参数, <实参1, 实参2, ……, 实参n> 
重复的语句组 
ENDM 

例9.11 把16位通用寄存器之值相加,并把结果存入寄存器AX。 
解:由于16位通用寄存器名是一些不同的符号,不能用计数的方法来依次访问它们,所以,我们需要用伪指令IRP来实现。 
IRPREG, <BX, CX, DX, SP, BP, SI, DI> 
ADD  AX, REG 
ENDM 

9.4.3 伪指令IRPC 
伪指令IRPC的作用与IRP相似,其实参表是一个字符串,并对字符串中的每个字符创建一组语句,所以,其重复次数是由该字符串中的字符数来确定。其一般使用格式如下: 
IRPC形式参数, 字符串 
重复的语句组 
ENDM 

例9.12 定义10个字节存储单元,保存数字0~9的平方数。 
解: 
IRPCX, 0123456789 
DB  X*X 
ENDM 

例9.13 把16位数据寄存器之值相加,并把结果存入寄存器DI。 
解:由于16位数据寄存器是AX、BX、CX和DX,它们的名称中只有第一个字符不同,所以,可以用伪指令IRPC来实现。 
XORDI, DI 
IRPCREG, ABCD 
ADD  DI, REG&X            ;符号&是连接运算符
五、条件汇编伪指令
条件汇编伪指令是告诉汇编程序:根据某种条件确定一组程序段是否加入到目标程序中。使用条件汇编伪指令的主要目的是:同一个源程序能根据不同的汇编条件生成不同功能的目标程序,增强宏定义的使用范围。 
条件汇编伪指令与高级语言(如:C/C++)的条件编译语句在书写形式上相似,在所起作用方面是完全一致的。 
9.5.1 条件汇编伪指令的功能 
条件汇编伪指令的一般格式如下: 
IFnnnn条件表达式 
语句组1 
[ELSE 
语句组2] 
ENDIF 

其中:IFnnnn是表9.2中的伪指令,“[…]”内的语句是可选的。 
条件汇编伪指令是在汇编程序把源程序转换成目标程序时起作用,其一般含义是:若条件汇编伪指令后面的“条件表达式”为真,那么,语句组1将被汇编;否则,语句组2将被汇编(如果含有ELSE伪指令)。 
语句组1或语句组2内还可以包有条件汇编伪指令,这时,就形成了嵌套的条件汇编伪指令。一个嵌套的ELSE伪指令总是与最近的、还没有与其它ELSE伪指令相比配的IFnnnn伪指令相比配。 
每条条件汇编伪指令的具体含义如表9.3所示。 
表9.3 条件汇编伪指令及其功能一览表 
伪指令含义 
IF exp若数值表达式exp的值不为0,则语句组1包含在目标文件中 
IFE exp若数值表达式exp的值为0,则语句组1包含在目标文件中 
IFDEF label若标号label有定义或被说明为EXTRN,则语句组1包含在目标文件中 
IFNDEF label若标号label没有定义,也没被说明为EXTRN,则语句组1包含在目标文件中 
IFB <参数>在宏引用时,若该形参没有相应的实参相对应,则语句组1包含在目标文件中 
IFNB <参数>在宏引用时,若该形参没有相应的实参相对应,则语句组1包含在目标文件中 
IFIDN <参数1>, <参数2>若参数1=参数2,则语句组1包含在目标文件中 
IFDIF <参数1>, <参数2>若参数1≠参数2,则语句组1包含在目标文件中 
IF1若汇编程序在第一遍扫描时,则语句组1包含在目标文件中 
IF2若汇编程序在第二遍扫描时,则语句组1包含在目标文件中 

9.5.2 条件汇编伪指令的举例 
例9.14 编写一个可用DOS或BIOS功能调用输入字符的宏定义。 
解: 
方法1:使用条件汇编伪指令IF 
INPUTMACRO 
IFDOS;当符号DOS不为0时,则使用DOS的功能调用 
MOV AH, 1H 
INT  21H 
ELSE;否则,将使用BIOS的功能调用 
MOV AH, 10H 
INT  16H 
ENDIF 
ENDM 

在引用宏INPUT时,汇编程序会根据DOS是否为0来生成调用不同输入功能的程序段。 
方法2:使用条件汇编伪指令IFDEF 
INPUTMACRO 
IFDEFDOS;当定义了DOS,则使用DOS的功能调用 
MOV AH, 1H 
INT  21H 
ELSE;否则,将使用BIOS的功能调用 
MOV AH, 10H 
INT  16H 
ENDIF 
ENDM 

在引用宏INPUT时,汇编程序会根据符号DOS是否已定义来生成调用不同输入功能的程序段。 
例9.15 编写一个可用功能调用输入字符的宏定义。 
解: 
READCHMACRO char 
MOVAH, 1H 
INT21H;接受一个字符,并存入AL中 
IFNB<char>;若参数char有实参与之对应 
IFDIF <char>, <AL>;若参数char≠AL,则把所输入字符保存到实参中 
 MOV char, AL 
ENDIF 
ENDIF 
ENDM
六、宏的扩充
MASM 6.11编程系统对宏定义及其相关语句进行了一定程度的扩充。虽然这些扩充给编程带来了一些方便,但它们不一定能被其它的汇编语言编程系统所接受,所以,程序员在使用这些方便的扩充功能时,要注意到可能带来的限制。 
下面介绍MASM 6.11编程系统对宏及其相关语句的扩充。 
9.6.1 宏定义形式 
在MASM 6.11编程系统中,其宏定义的一般形式如下: 
宏名MACRO  [参数1[:tag]] [,参数2[:tag]...] 
[LOCAL varlist] 
… 
[EXITM [value]] 
ENDM;宏定义体内的局部变量和标号 
;宏的定义体 

对上述宏定义的说明与9.1.1节中的说明完全一致,其需要增加的说明如下: 
tag—— 其值可以是REQ、=<缺省值>或VARARG 
REQ指定该参数是不可缺少。在宏引用时,若该参数不对应某个“实参”,那么,汇编程序会报错; 
=<缺省值>在宏引用时,若不指定该参数所对应的“实参”,那么,该参数就取其缺省值; 
VARARG该参数对应一个可变长的实参表,各实参之间用逗号分开;若参数的属性指定为VARARG,那么,该参数一定要是最后一个参数。 
有关该属性的应用,请见随后9.6.7节中的举例。 

value—— 宏功能的返回值,其为可选项。 

9.6.2 重复伪指令REPEAT 
重复伪指令REPEAT与前面9.4.1节中伪指令REPT在功能和使用方式方面完全一致,设置该伪指令的主要原因是保证与先前版本的兼容性。 
伪指令REPEAT的使用方式如下: 
REPEAT数值表达式 
语句序列;被重复的汇编语言语句 
ENDM 

9.6.3 循环伪指令WHILE 
循环伪指令WHILE的使用方式如下: 
WHILEExp 
语句序列;被重复的汇编语言语句 
ENDM 

其功能是先判断表达式Exp是否为假(或为0),若是,则终止该伪指令的功能,否则,循环汇编下面的指令块。表达式Exp是能在汇编时计算出其值的数值表达式。 
例9.16:编写一个带有参数result和k的宏,其功能是把1+2+…+k的累加和存入result之中,其中:result是不可缺省的,k的缺省值为1。 
解: 
SUMMACRO result:REQ, k:=<1> 
LOCAL n 
n = k 
movresult, 0 
WHILEn 
add    result, n 
n = n - 1 
ENDM 
ENDM 

有了上面的宏定义,就可书写下面的宏引用来实现其相应的功能: 
SUMax, 10;寄存器ax=1+2+3+…+10 
SUMbh;寄存器bh=1,因为第二个形参取其缺省值 
SUMecx, 100;寄存器ecx=1+2+3+…+100 
SUMdata, 20;存储单元data=1+2+3+…+20
七、循环伪指令FOR
循环伪指令FOR与9.4.2节中伪指令IRP在功能上完全一致,设置该伪指令的原因也是为了保证与先前版本的兼容性。 
伪指令FOR的使用方式如下: 
FOR parameter[:REQ|:=<default>], <argument [, argument]...> 
语句序列;被重复的汇编语言语句 
ENDM 

其中各参数的说明如下: 
parameter一个合法的标识符,它依次取后面参数表中的值。在指令序列中,该变量的每次出现都用其值所替换; 
:REQ说明该变量的取值不能为空; 
:=<default>指定该变量的缺省值,若后面的参数表缺省某个参数(用连续的逗号),这时,该循环变量将取其缺省值; 
Argument参数表中可含有文本、符号、字符串或数值常量,每个参数之间要用逗号分割。 

例如: 
FORdata:=<?>, <"123", , 21, 0> 
DB data 
ENDM 
…… 
FORreg:REQ, <ax, bx, dx> 
push reg 
ENDM 

该语句在宏展开时,将得到下列语句: 
DB "123" 
DB  ? 
DB  21 
DB  0 
…… 
push  ax 
push  bx 
push  dx 
9.6.5 循环伪指令FORC 
循环伪指令FOR与9.4.3节中伪指令IRPC在功能上完全一致,它也是为保证与先前版本的兼容性而设置的。 
伪指令FORC的使用方式如下: 
FORCparameter, <string> 
语句序列;被重复的汇编语言语句 
ENDM 

其中各参数的说明如下: 
parameter:一个合法的标识符,它依次取字符串中的每个字符。在语句序列中,该变量的每次出现都用其值所替换; 
String:一个字符串或被定义为字符串的符号名,字符串中的空格也被算为一个字符。括号"<"、">"是必不可少的。 

例如: 
FORCdata, <1?3> 
 DB data 
ENDM 
…… 
FORCreg, <abd> 
push reg&x 
ENDM 

该语句在宏展开时,将得到下列语句: 
DB 1 
DB ? 
DB 3 
…… 
push ax 
push bx 
push dx
八、转移伪指令GOTO
转移伪指令GOTO用于实现宏定义体内的转移功能,其使用方式如下: 
   GOTO 标号 
   … 
:标号     ;标号后不能写指令,但可写注释 
   … 
该伪指令的功能是使汇编程序转移到“标号”处汇编,它只能在宏定义MACRO、REPEAT、WHILE、FOR和FORC等语句块内使用,该标号也只在该语句块内有效。 
9.6.7 宏扩充的举例 
例9.17:编写一个给任意寄存器或存储单元清零的宏定义。 
解: 
Clearlist : VARARG 
FORdata:REQ, <list> 
mov data, 0 
ENDM 
ENDM 

有了上面的宏定义,下面的二个宏引用都是正确的,尽管宏引用时所带的参数个数是不同的。这正是参数属性VARARG的作用所在。 
Clear   ax, bx 
…… 
Clear   si, cl, MemVar, edx      ;MemVar是内存变量,任意类型都可以 
这二个宏引用展开时所得到的指令如下: 
mov ax, 0 
mov bx, 0 
…… 
mov si, 0 
mov cl, 0 
mov MemVar, 0 
mov edx, 0

 

转载于:https://www.cnblogs.com/nikosoft/p/4139073.html

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

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

相关文章

运维秘籍:防止数据丢失“六脉神剑”

服务器数据存储安全是保障服务器正常运行的重要的环节&#xff0c;同时也是企业网络信息化建设的核心。每一家企业的管理层人员都非常重视存储在服务器的重要数据&#xff0c;包括&#xff1a;各类管理中所产生的机密办公文件、经营中所积累的客户资料、研发中所涉及的重要文件…

CSS中设置border属性为0与none的区别

在我们设置CSS的时候&#xff0c;对标签元素不设置边框属性或者取消边框属性一般设置为&#xff1a;border:none;或border:0;两种方法均可。 border:none;与border:0;的区别体现有两点&#xff1a;一是理论上的性能差异&#xff1b;二是浏览器兼容性的差异。 1.性能差异 【b…

windows下Python+Editplus windows Python开发环境

From: http://www.jb51.net/softjc/34898.html 点评&#xff1a;Python的安装程序以及源代码可以从其官方网站http://www.python.org/获取。以Windows XP、Python 3.1.3为例&#xff0c;在Windows下安装Python的过程如下。&#xff08;1&#xff09;从Python官方网站 http://…

Lightbox JS v2.0

概要&#xff1a;Lightbox JS 是一个简单而又谦恭的用来把图片覆盖在当前页面上的脚本. 它能被快速安装并且运作于所有流行的浏览器.最新更新 Version 2.0图片集: 分组相关的图片并且能轻松的导航它们 视觉特效: 奇特的自适应调整 向后兼容: yes! 点击这里查看实例演示如何使用…

求和

Problem Description 求Sn222222…22…222&#xff08;有n个2&#xff09;的值。 例如&#xff1a;222222222222222&#xff08;n5&#xff09;&#xff0c;n由键盘输入。 Input n Output 和 Sample Input 5 Sample Output 24690 #include <iostream> using namespace s…

PHP Fatal error: Uncaught think\\exception\\ErrorException: error_log相关解决方法

解决方法&#xff1a;切换到tp5目录然后使用chmod -R 777 tp5来解决&#xff0c;当然不太建议这样做&#xff0c;这不符合我们在线上的操作方式。一种比较推荐的做法是执行chmod -R daemon:daemon tp5来进行处理&#xff0c;这是因为在Mac上默认的Apache用户为daemon&#xff0…

React开发(150):判断方法有避免报错

this.props.onHandleDelete&&this.props.onHandleDelete();

《算法》C++代码 前言

现在大二正在上《数据结构》课&#xff0c;课内的书上代码实现很喜欢无脑用类、变量名字很长&#xff0c;而且常常实现太繁琐&#xff0c;并且代码有些无法运行&#xff0c;这些对于老手无所谓&#xff0c;但初学者看起来却会很不舒服。因此写点自己的代码&#xff0c;大家可以…

Linux下的分区工具

Linux下的分区工具 来源:http://www.cnblogs.com/rootq/articles/1487201.html[rootlocalhost gxlinux]# df -Th#查看已经挂载上的文件分区大小以及格式(当然你的系统必须有空闲的空间不用了)文件系统 类型 容量 已用 可用 已用% 挂载点/dev/sda1 ext3 2.9G 2…

Linux常用命令大全(非常全!!!)

linux系列之常用运维命令整理笔录 Linux常用命令大全&#xff08;非常全&#xff01;&#xff01;&#xff01;&#xff09; 最近都在和Linux打交道&#xff0c;感觉还不错。我觉得Linux相比windows比较麻烦的就是很多东西都要用命令来控制&#xff0c;当然&#xff0c;这也是…

旋转动画用控件RotateView

旋转动画用控件RotateView 最终效果&#xff1a; 源码&#xff1a; RotateView.h 与 RotateView.m // // RotateView.h // RotateAnimationView // // Created by YouXianMing on 14/12/8. // Copyright (c) 2014年 YouXianMing. All rights reserved. //#import <UIKit…

UPS分类:直流UPS和交流UPS

以下资料来源于IT168术语详解&#xff1a;http://detail.it168.com/UPS从结构上一般分为直流UPS(DC-UPS)和交流UPS(AC-UPS)两大类。(1)直流UPS直流不间断电源由两个基本单元组成。分别是整流器、蓄电池。其原理结构方框图如下&#xff1a;其工作过程是&#xff1a;当市电正常时…

在python中可以使用urllib方便的实现图片和flash下载

非线程安全import urllib url “http://www.udooo.com/cooperate/qq/images/081128/left.swf” path “c:/spider/left.swf” data urllib.urlopen(url).read() f file(path,”wb”) f.write(data) f.close()线程安全python中还有更简洁的方法&#xff1a;import urllib ur…

HTTP1.0和HTTP1.1和HTTP2.0的区别

HTTP1.0和HTTP1.1和HTTP2.0的区别 1 HTTP1.0和HTTP1.1的区别 1.1 长连接(Persistent Connection) HTTP1.1支持长连接和请求的流水线处理&#xff0c;在一个TCP连接上可以传送多个HTTP请求和响应&#xff0c;减少了TCP的建立和关闭连接的消耗和延迟&#xff0c;在HTTP1.1中默…

PowerShell实战1:Ping_Test

功能&#xff1a;批量测试远程主机的Ping值&#xff0c;以及根据TTL值来判断是否为Windows主机。使用&#xff1a;在C:\IP.txt中加入需要测试的主机IP或域名&#xff0c;一行一个。例如&#xff1a; www.google.com www.baidu.com www.cha123.com www.yahoo.com www.msn.com源码…

5年后你最想要什么?

当你对自己的生命经常问为什么会这样的时候&#xff0c;你不妨试着问一下自己&#xff0c;你是否很清楚地知道自己要的是什么&#xff1f;如果连你自己要的是什么都不知道的话&#xff0c;那么爱你的亲人如何帮你安排呢&#xff1f;又岂能无端地怪亲人没有给你开路呢&#xff1…