【文档说明】汇编语言程序设计及上机指导汇编语言语法课件.pptx,共(51)页,192.697 KB,由我爱分享上传
转载请保留链接:https://www.ichengzhen.cn/view-44781.html
以下为本文档部分文字说明:
汇编语言程序设计及上机指导汇编语言语法5.1.1汇编语言程序的基本概念指令与伪指令的集合构成汇编语言语句.MODELSMALL;定义内存工作模式为小模式.386;定义指令系统为80386指令集.STACK;定义1K个字节的堆栈段.DATA;数据段开始DATA1DD12340000H;定义第
一个32位数据的值为12340000HDATA2DD5678H;定义第二个32位数据的值为5678HSUMDD?;定义用来存放前两个数据之和的第三个数据.CODE;代码段开始,数据段结束.STARTUP;程序开始MOVEAX,DA
TA1;取第一个数到EAXADDEAX,DATA2;求和MOVSUM,EAX;保存结果(12345678H)至SUM.EXIT0;程序结束,正常返回到操作系统END;结束汇编5.1.2汇编语言的基本语法
一、字符集•英文字符:A~Za~z•数字字符:0~9•算术运算符:+-*/•关系运算符:<=>•分隔符:,(逗号);(分号)()(括号)[]'(引号)(空格)TAB(制表符)•控制符:CR(回车)LF(换行)FF(换页)•其它字符:$&_(下划线)?·@%!二
、标识符1)标识符的第一个字符必须是字母、问号“?‖、“@‖符、或下划线“_‖;2)从第二个字符开始可以是字母、数字、或“?‖、“@‖、“_‖;3)一个标识符的长短可以由1~31个字符组成。例如:X,GAM_31,?JACK5是正确的;而8
P,DATA8是不正确的。三、保留字寄存器名、指令助记符、伪操作命令、表达式运算符,以及属性操作符等都是系统专用的保留字。这些保留字是不能用作标识符的。四、语句•一条语句一般只占一行,超过一行时必须用续行符号“\‖指示•两条语句不能写在同一行。•语句可以有注释,一般
写在语句之后或单独占一行,是以“;”开始的字符串。5.2汇编语言的数据和表达式•汇编语言能识别的数据是常量、变量和标号。5.2.1常量•常量是汇编时已经确定的值,主要用于伪指令中给变量赋值,或作为指令语句中的立即数或存储器操作数的组成部分。一.常量的类型数据形式格式×取值范围举
例注释二进制数×…×B0~110010011B二进制数以B结尾八进制数×…×Q0~7123Q八进制数以Q结尾十进制数×…×D0~9256D,3458十进制数以D结尾或者缺省十六进制数×…×H0~9A~F
0A3H,12345H十六进制数以H结尾,最前面必须是0~9字符或字符串'×…×'ASCII字符'ABC'两端必须加’或”二.符号定义伪指令用于给程序中多次出现的同一个常量或表达式赋一个符号名,也可以为其它符号名取一
个新名字,并赋给新的类型属性。(1)EQU伪指令例:FIRSTEQU1;定义常数SECONDEQUFIRST*3+8;定义数值表达式ADDR1EQUDS:[EBP+4];定义地址表达式DWORDSEQUTHISDWORD;定义下面的字节变量为双字
类型BYTESDB10DUP(0)ADDR2EQUWORDPTRBYTES;重新定义变量BYTES的名字和属性START:MOVEAX,EBXGOONEQUFARPTRSTART;重新定义标号START的名字和属性COUNTEQUECX;为ECX
重新取名注意:该等值语句只作为符号定义用,不产生任何目标代码,也不占用存储单元,并且不能是程序中曾经定义过的符号名。(2)“=”伪指令“=”伪操作命令与EQU具有相同的功能,但它定义的符号允许重新定义。例:PERSON=10;
定义PERSON等于10PERSON=PERSON+5;重新定义PERSON等于155.2.2变量变量的值可以在程序运行过程中可随时修改,变量名是存放数据的存储单元符号地址,变量的值为对应存储单元的内容。
一.变量的属性•段属性(SEG),指变量所在段的段基址。•偏移地址属性(OFFSET),指变量所在段中的偏移地址,即变量所在地址与段基址之间的字节距离。•类型属性(TYPE),指变量占用存储单元的字节数。–
若占用一个字节,称为字节变量,其类型为BYTE;–若占用两个字节,称为字变量,其类型为WORD;–若占用四个字节,称为双字变量,其类型为DWORD;–若占用六字节,其类型为FWORD;–若占用八字节,其类型为QWORD;–若占用十字节,其类型为TBY
TE。二.变量定义伪指令就是为数据分配存储单元,且对这个存储单元取一个名字,即变量名。语句的格式如下:[变量名]DB/DW/DD/DF/DQ/DT表达式1,表达式2,……变量名是可选的,DB/DW/DD/DF/DQ/DT是伪操作命令必须选用一种,表达式是赋给变量的初值,常
见的有如下几种:(1)数值变量定义语句例:D_BYTEDB30H,40HDB50HD_WORDDW1234H,5678HD_DWORDDDD_DWORDD_TBYTEDT?D_FWORDDF123456
7890ABHD_QWORDDQ1122334455667788H(2)字符串变量定义语句可以用DB来实现,即为串中的每一个字符分配一个字节存储单元。字符串必须用引号括起来,并且不超过256个字符,它们在内存中自左至右把字符的ASCII
码按地址递增顺序依次存放。例:STRING1DB'ABCDEFG'用DW也可以定义字符串变量,即给两个字符组成的字符串分配两个字节存储单元,它们在内存中的顺序是前一个字符为高字节,存放在高地址,后一个字符为低字
节,存放在低地址。例:STRING2DW'AB','CD','EF'(3)?语句存储单元中不预置确定的值,常用来预留存储单元,存放程序的中间结果或最终结果。例:FIRSTDB?;分配一个字节单元SECONDDD?,?,?;分配三个双字单元(4)带DUP的变量定义语句DUP是重复
数据定义操作符,可以为若干重复数据分配存储单元,并赋给相应的变量名。例:D1DB5DUP(0)D2DW10HDUP(5678H)D3DD20HDUP(?)•第一条语句为变量D1分配5个字节单元,每个单元初始值都为0;•第二条语句为变量D2重复分配10H个字
单元,每个单元初始值都为5678H,共占有20H个字节;•第三条语句为变量D3保留20H个双字单元,没有定义初始值。D4DB200DUP(4DUP(6),8)•表示为变量D4重复分配200个数据序列'6,6,6,6,8',共占有1000个字节单元。三.内存定位和定义数制伪指令(
1)ORG伪指令和当前位置计数器$汇编时将段名填入段表,同时为该段配备一个初值为0的位置计数器$。计数器依次累计段内语句被汇编后生成的目标代码字节个数。可用ORG伪指令把位置计数器$的值设置成需要的值。•在数据段中,ORG后面的数据定义伪指令就从指定位置进行分配单元;•在代码段中,
ORG后面的一条指令语句就从指定位置生成目标代码;•表达式的值应该是非负的整数。例:ORG0F0H;从0F0H开始安排数据ORG$+10H;跳过10H个字节后安排数据DW1,$+4,$+4;100H单元的字值为1,102H单元的字值
;为106H,104H单元的字值为108HARRAYDB12,34,56,5DUP(?);定义字节数组LENEQU$-ARRAY;LEN的值为ARRAY变量所占的字节数8(2)EVEN伪指令用来把段内位
置计数器的值置为偶数地址边界对齐,如果遇到EVEN时计数器$值非偶数,则汇编程序自动插入NOP指令(在代码段中),使其为偶数;或者将$的值加1(数据段中)。(3).RADIX伪指令宏汇编默认常量基数都是十进制数,可用.RAD
IX伪命令把缺省基数改为2~16范围内的任意基数:.RADIX<表达式>其中,表达式与当前基数无关,一定是十进制数。例:MOVAX,0FFHMOVBX,20.RADIX16MOVCX,0FFMOVDX,20D其中
AX和CX寄存器的内容相同,BX和DX寄存器内容相同。5.2.3标号标号之后必须有一个冒号(:),标号也可以单占一行。一.标号的属性•段属性(SEG),指标号所在段的段基址。•偏移地址属性(OFFSET),指标号所在段中的偏移地址,即标
号所在地址与段基址之间的字节距离。•距离属性或类型属性(TYPE),标号可作为转移和调用指令的目标地址,也可作为过程定义伪指令的过程名。–当标号只允许作为段内转移或调用指令的目标地址时,距离属性为NEAR;–当标号作为段间转
移或调用指令的目标地址时,距离属性为FAR。例如:JMPLABEL1;程序跳转到标号LABEL1的位置CALLFARPTRSUBPROGRAM;调用SUBPROGRAM过程(FAR)LABEL1:┅;LABEL1为段内转移标号(距离属性缺省为NEAR)┅LABEL2:;LABEL2为段
内转移标号,单独占一行┅SUBPROGRAMPROCFAR;SUBPROGRAM是属性为FAR的过程┅RET标号的距离属性可用LABEL伪指令加以改变。二.LABEL伪指令(1)与变量连用用来给相连的变量取一个新的名字,并指定新的类型属性。例:B_VAR1LABELBYTEW_VAR1D
W3456HW_VAR2LABELWORDD_VAR2DD87654321H给字变量W_VAR1一个新名字B_VAR1,类型属性BYTE。如果以字类型访问该变量,应使用变量名W_VAR1;而以字节类型访问该变量时,应使用B_V
AR1。如果想按字访问D_VAR2变量,则可以用W_VAR2。注意:B_VAR1和W_VAR2都是给变量增加类型属性,并不另外占用存储单元(2)与标号连用用来给相连的指令地址(即标号)定义一个新的标号,并指定新的距离属性。例:DISTFARLAB
ELFARDISTNEAR:MOVEAX,EBX给近标号DISTNEAR取一个新的标号名DISTFAR,距离属性修改为FAR。当其它代码段中的转移或调用指令引用时,可使用标号DISTFAR,而在本段引用时,只要使用
标号DISTNEAR即可,但它们实际上是指向同一条指令。用LABEL伪指令的定义,实现了按不同的标号名和不同的转移方式而转移到同一个标号的目的。5.2.4表达式和运算符一、算术运算符•包括+、-、*、/、MOD、SHL和SHR共七种;•+、-、*、/参加运算的数和运算结果均为整数;•除法
运算为整除,而模除的运算结果为余数;•左移或右移运算符可使二进制数左移或右移若干位,相当于二进制数进行乘法或除法运算。例:TEMP=10+5;TEMP=15TEMP=TEMP-3;TEMP=12TEMP=TEMP*5;T
EMP=60TEMP=TEMP/9;TEMP=6TEMP=TEMPMOD4;TEMP=2TEMP=-TEMP;TEMP=-2MOVAL,11BSHL5;(AL)=01100000B注意:除了加和减运算符可以使用变量或标号外,其它算术运算符只适用于常量的数值运算。
二、逻辑运算符有AND、OR、XOR、NOT共四种;•只适用于对常量进行逻辑运算,运算是按位进行的;•运算符与逻辑运算指令助记符相同,但在语句中的位置不一样,表达式中的逻辑运算符是在汇编时完成运算的;而逻辑运算指令运算在执行指令时进行。例:MOV
AL,NOT10100101B;(AL)=01011010BMOVAL,11011011BAND00001111B;(AL)=00001011BMOVAL,11100001BOR10000101B;(AL)=11100101BMOVAL,101
11011BXOR00100100B;(AL)=10011111B三、关系运算符包括EQ、NE、LT、GT、LE、GE共六种;•可对常量或同一段内的存储器地址进行比较运算;•若条件满足,运算结果为真,输出结果为全“1‖;•若不
满足条件,运算结果为假,输出结果为全“0‖。例:MOVBX,10EQ1010B;10等于1010B为真,(BX)=0FFFFHMOVDX,20HGT32;20H大于32为假,(DX)=0四、数值返回运
算符运算对象必须是存储器操作数,即变量或标号。(1)SEG运算符:返回该变量或标号所在段的段基址。例如:MOVAX,SEGVAR如果变量VAR所在段的段基址为1000H,则该指令执行的结果等效于MOVAX,1000H(2)OFFSET运算符:返回该变量或标号所在段内的偏
移地址。例如:MOVDI,OFFSETVAR如果变量VAR在1000H段内的偏移地址是100H,则该指令执行的结果等效于:MOVDI,100H(3)TYPE运算符:返回该变量的类型属性或者标号的距离属性。例:V1DB1,2,3V2DW1020H,304
0HV3DD12345678HPFLABELFARPN:MOVAH,TYPEV1;等效于MOVAH,1MOVAL,TYPEV2;等效于MOVAL,2MOVDL,TYPEV3;等效于MOVBL,4MOVDH,TYPEPF;等效于MOVBH,-2属性
与返回数值的关系变量/标号属性返回数值字节变量BYTE字变量WORD双字变量DWORD三字变量FWORD四字变量QWORD十字节变量TBYTE1246810标号NEAR标号FAR–1[FFH]–2[FEH]4.LENGTHOF运算符该运算符加在变量名之前,返回的数值是变量中所定义的元素个数。D
1DW10HDUP(0),1234HD2DB20HDUP(2DUP(0),1)D3DQ1234H,5678HD4DB‗ABCDEFGH‘D5DD12H,34H,\;加一个续行符,表示一条伪指令占两行56H,78HD6DD12H,34H;未加续行符,
则表示这两行是两条伪指令DD56H,78HMOVAL,LENGTHOFD1;(AL)=11HMOVAL,LENGTHOFD2;(AL)=60HMOVAL,LENGTHOFD3;(AL)=2HMOVAL,LENGTHOFD4;(AL)=8
HMOVAL,LENGTHOFD5;(AL)=4HMOVAL,LENGTHOFD6;(AL)=2H5.SIZEOF运算符该运算符加在变量名之前,返回的数值是变量所占的总字节数,且等于LENGTHOF和TYPE两个运算符返回值的乘积。例如,对于上例中的变量
,SIZEOF的返回值如下所示:MOVAL,SIZEOFD1;(AL)=22H,即20H*2HMOVAL,SIZEOFD2;(AL)=60H,即60H*1HMOVAL,SIZEOFD3;(AL)=10H,即8H*2HM
OVAL,SIZEOFD4;(AL)=8H,即8H*1HMOVAL,SIZEOFD5;(AL)=10H,即4H*4HMOVAL,SIZEOFD6;(AL)=8H,即2H*4HLENGTH运算符返回变量中所定义的元素个数,如果变量是用重复数据操作符DUP说明的,则
返回DUP前面的数值;如果没有DUP说明,则返回的值总是1。例:D1DW10HDUP(0)D2DB20HDUP(0)D3DW1234H,5678HD4DB'ABCDEFGH'MOVAL,LENGTHD1;(AL)=10HMOVAL,LENGTHD2;(AL
)=20HMOVAL,LENGTHD3;(AL)=1HMOVAL,LENGTHD4;(AL)=1HSIZE运算符返回变量所占的总字节数,且等于LENGTH和TYPE两个运算符返回值的乘积。例如,对于上例中的变量D1、D2、D3、D4,SIZE的返回值如下所示:MOVAL
,SIZED1;(AL)=20HMOVAL,SIZED2;(AL)=20HMOVAL,SIZED3;(AL)=2HMOVAL,SIZED4;(AL)=1H五、修改属性运算符(1)PTR运算符格式:<类型>PTR<地址表达式>根据地址表达式的不同,所赋给的新类型可以是
BYTE、WORD、DWORD、FWORD、QWORD、TBTYE、NEAR、FAR等,它们只在所在的指令内有效。例:TABLEDB1,2,3,4,5,6,7,8ADDWORDPTR[DI],100;指明目的操作数为字类型JMPDWORDPTR[BX];指明为段间转移
MOVEAX,DWORDPTRTABLE;临时修改TABLE为双字类;型,(EAX)=04030201H(2)THIS运算符把它后面指定的类型或距离属性赋给当前的变量、标号或地址表达式,但不分配新的存储单元,往往与伪指令EQU或=连用,为当前存储单元定义一个指定类型的变量或标号,类型属性
也可以是BYTE、WORD、DWORD、FWORD、QWORD、TBTYE、NEAR、FAR等。例:DATEQUTHISWORDPOINTEQUTHISFAR第一条语句将变量DAT的类型属性定义为字,不管DAT原来的类型是什么,
从本语句开始,DAT成为字节变量;第二条语句将标号POINT的距离属性定义为FAR,不管POINT原来的距离属性是什么,从本语句开始,POINT成为远标号。六、其它运算符(1)高低分离运算符•HIGH运算符和LOW运算符分别用于从16位运算对象中分离出高字节和低字节。从MA
SM6.0开始引入了HIGHWORD运算符和LOWWORD运算符分别用于从32位符号常量中分离出高字和低字部分。例:MOVAH,HIGH5678H;(AL)=56HDATA16EQU1234HMOVAL,LOWDATA1
6;(AL)=34HDATA32EQU1234FFFFHMOVAX,LOWWRODDATA32;(AX)=0FFFFH(2)方括号运算符:运算符中可以是数组变量的下标或地址表达式,以区别操作数和操作数地址。例:ARRAYDB1,2,3,4,5;ARRAY为数组变量
MOVAL,ARRAY[4];”4‖为下标,(AL)=5MOVBX,OFFSETARRAY;(BX)=ARRAY的偏移地址MOVAH,[BX];(AH)=1MOVDX,WORDPTRARRAY[1];(DX)=302H(3)运算符的优先级:一般可以用括号来改变运算符的优先级别。例:MOVAL,18
OR5AND10;AL=18(12H)MOVAL,(18OR5)AND10;AL=2运算符的优先级表4.3运算符的优先级别优先级别运算符0(„),[„],{„},LENGTHOF,WIDTH,SIZEOF,MASK1PTR,OFFSET,SEG,TYPE,THIS,C
S:,DS:,SS:,ES:2HIGH,LOW,HIGHWORD,LOWWORD3*,/,MOD,SHL,SHR4+,–5EQ,NE,LT,LE,GT,GE6NOT7AND8OR,XOR高级低级9SHORT5.3宏汇编语言的伪指令•符号定义、变量定义、程序分段定义、过程定义、模块定
义、宏定义、条件汇编、以及格式和列表控制等。5.3.1段定义和程序说明伪指令具体来说规定段的起始和结束指定属性开始地址边界段类型同名段如何结合在一起有两种段定义简化段定义:对MASM5.0以上版本完整段定义:对所有版本一、完整分段定
义伪指令1.段定义伪指令SEGMENT/ENDS——将程序分成段:代码段,数据段,堆栈段,附加段。格式:段名SEGMENT[定位类型][组合属性][‗类别名’]…(段体)…段名ENDS功能:指出段名和段的各种属性,并表示段的开始和结束位置。▲段定义由伪
操作SEGMENT开始、ENDS结束。其中:SEGMENT和ENDS必须成对出现,且语句前必须有段名,段名必须相同。▲SEGMENT和ENDS语句之间可以有指令和其他伪指令,表示存放在该段内存的变量、指令或其他伪指令对该段内存的处理▲程序中可以定义多个段。▲程序经汇编、连接及装入内存后,
段名为一具体的段值。合法标识符,有段基地址和段内偏移量两个属性,与某个存储单元相联系。(1)定位类型——用于告诉链接程序,链接时(各模块.obj)本段首地址的边界定位方式,常有四种:①PARA:段的起始地址必须是16的倍数(XXXX0H),这是一种默认方式。②PAGE:段的起始地址必须是256
的倍数(XXX00H),256字节为一页,在页的起点上。③WORD:段的起始地址必须是偶数(XX…0B)。④BYTE:段的起始地址可以是任何地址。(2)组合类型——在多模块(每个模块有自己的代码段、数据段、堆栈段)组合时,告诉Link程序本段与其他模块中同名段的组合链
接关系。①NONE:本段与其他同名段无组合关系,并有自己的段起始地址,这是一种默认方式。②PUBLIC:在满足定位类型的前提下,LINK程序将其与其他模块中的同名段邻接在一起,共用一个段地址。③STACK:同PUBLIC。链接以后
作为堆栈段,并自动初始化SS、SP。若程序中不说明STACK,则必须由用户在程序的开始处,自己通过语句设置SS、SP。④COMMON:各模块中同名段重叠覆盖,有着相同的起始地址。段的长度取决于最长的COMMON段。段的
内容为所链接的最后一个模块中COMMON段的内容。⑤MEMERY:链接在其他所有段的后面(高端存储区)。若有多个MEMERY段,则只认第一个,其余按COMMON处理。(3)段字属性•在32位80X86微处理器中,新增加了USE属性说明。对于16位CPU默
认的是16位段,即USE16。而对于汇编32位80X86CPU指令时,它默认采用32位段,即USE32。但可以使用USE16指定标准的16位段。若在程序开头使用了.386伪指令(见简化段定义伪指令),缺省类型为32位段字长。注意,在禁止用80386的情况下
,使用USE选择项将导致出错。(4)段类别名属性•类别名可以是任何合法的名字,必须用单引号括起来。在连接处理时,链接程序把类别名相同的所有段存放在连续的存储区内。典型的类别名如:‘DATA‘,‘STACK‘,‘CODE‘
。以上是定位类型、组合类型、段字和类别名四个参数的说明,各参数之间用空格分隔。在选用时,可以只选其中一个或两个参数项,但不能交换它们之间的顺序。2.段寄存器说明伪指令格式:ASSUME段寄存器:段名[,段寄存器:段名,…]①设定特定的Sreg指向特点的
段,说明源程序中定义的段应由哪一个Sreg去寻址。不如此,汇编程序无法生成目标代码程序。②ASSUME并未真正的将段地址装入相应的Sreg。Sreg的初值还必须由用户在程序的开始处用MOV指令来设置(C
S除外)。(1)DS和ES的装入DS和ES的装入可以通过给寄存器赋初值的指令来完成。但是应注意到,由于段寄存器不能用立即数寻址方式直接传送,因此装入段基址必须借助于通用寄存器进行间接传送。例:CODESSEGMENTASSUMECS:CODES,DS:DATAS
,SS:STACKS,ES:EXTRSSTART:MOVAX,DATASMOVDS,AXMOVAX,EXTRSMOVES,AX┅CSEGENDS(2)SS的装入•一种方法是在SEGMENT语句中,组合类型选用STACK,并在ASSUME语句中,把堆栈用
的段指派给段寄存器SS。STACKSSEGMENTPARASTACKDB100HDUP(?)STACKSENDS┅CODESSEGMENTASSUMECS:CODES,SS:STACKS┅•另一种方法是在SEGMENT语句中,组合类型未选用STACK参数,或者在
程序中使用另一个堆栈段时,可采用类似于DS和ES的装入方法,用传送指令实现对SS的装入操作。(3)CS和IP的装入•CS和IP的装入通常是按照结束伪指令指定的地址来自动完成的。结束伪指令的格式是:END[<起始地址>
]•起始地址是一个标号或地址表达式,这个地址是程序装入内存后的起始点,它的段基址和偏移量就是CS和IP的内容。3.组定义伪指令GROUP•格式:组名GROUP段名[,段名……]•将程序中若干不同名的段
集合成一个组,并赋予一个组名,使它们都装在一个64KB的物理段中,这时组内不同类型的段运行时共用一个Sreg,组内各段间的跳转都可以看作段内跳转。例:STACKSEGSEGMENTSTACK;定义堆栈段DB256DUP(?)STACKSEGENDSDATA1SEGMENTWORDPUBLI
C'CONST'CONS1DW100;定义数据段1DATA1ENDSDATA2SEGMENTWORDPUBLIC'VARS'VAR1DW?;定义数据段2DATA2ENDSDATAGROUPGROUPDATA1,DATA2;组合两个数据段,以DATAGROUP为段组名
CODESEGSEGMENTPARAPUBLIC'CODE';定义代码段ASSUMECS:CODESEG,DS:DATAGROUP,SS:STACKSEGSTART:MOVAX,DATAGROUPMOVDS,AX;DS赋初值对该组寻址MOVAX,CONS1;AX=100MOVVA
R1,AX;VAR=100MOVAX,OFFSETVAR1;AX=2MOVAX,OFFSETDATA1;AX=2(已分配2个字节内存单元)MOVAX,OFFSETDATA2;AX=4(已分配4个字节内存单元)MOVAX,4C00HINT21H;DOS功能调用,可正常返回到操作系统CODESEG
ENDSENDSTART;程序结束二、简化分段定义伪指令在MASM5.0版本以上的宏汇编语言中段的定义可以非常简单。.MODEL<存储模式>;定义程序的存储模式.STACK<长度>;定义堆栈段,长度缺省为1K字节.CODE[<名字>];定义代码段.DATA;定义数据段.DATA?;
定义数据段,但初值不确定.FARDARA[<名字>];定义远调用数据段.FARDARA?[<名字>];定义远调用数据段,但初值不确定.CONST;定义只读常数数据段.STARTUP;程序起始点,并初始化DS、SS.EXIT0;程序结束点,返回到操作系统例:.MODELSMALL;定义小型内存模
式.386;可以汇编386指令.STACK100;定义堆栈段,长度为100字节.DATA;数据段开始XDD12345678HYDD87654321HZDD?,?.CODE;代码段开始.STARTUP;程序开
始MOVEAX,XMULYMOVZ,EAXMOVZ+4,EDX.EXIT0;程序结束,返回,;相当于MOVAX,4C00H和INT21H两条指令END;汇编结束1.定义内存模式伪指令.MODEL存储模式[,语言类型][,操作系统类型]
[,堆栈类型](1)存储模式:①TINY:微型模式,程序中的数据和代码放在同一64K段内,这也就是后缀为.COM的程序。这种模式是MASM6才引入的。②SMALL:小型模式,程序中的代码放在64KB的数据段内,数据放在64KB代码的段内(
包括数据段、堆栈段和附加段公用一个段),因而对代码和数据的访问可通过近程(NEAR)调用来实现。一般程序默认的都是该模式。③MEDIUM:中型模式,程序中的数据放在64KB的数据段内,代码量大于64KB,因而可安排在不同段内。这样,数据是
近程的,而代码是远程的。④COMPACT:压缩模式,程序中的所有代码放在一个64KB的代码段内,而数据区可以大于64KB。这样,对代码的访问是近程的,而数据是远程的。⑤LARGE:大型模式,程序中的数据和代码
均大于64KB,但静态(常数)数据限制在64KB之内。对程序和数据的访问默认都是远程的。⑥HUGE:巨型模式,程序中的数据和代码均大于64KB,静态数据也可以大于64KB。这样,对代码、数据和数组的访问都是远程的。⑦FLAT:平展模式,用于创建一个
32位的程序,它只能运行在32位80X86CPU上。DOS下不能使用FLAT模式,而编写32位Windows程序时,必须采用FLAT模式。(2)语言类型:•由它来告诉汇编程序将使用什么样的标识符的命名风格、子程序的调用和返回约
定等。可使汇编语言程序与其它语言程序达到共享的目的。有效的语言类型为:C(C语言)、SYSCALL(系统调用)、STDCALL(标准调用)、Basic(Basic语言)、Fortran(Fortran语言)、Pascal(Pascal语言)等。(3)操作系统类型:•OS_DOS是当前唯一支持
的选项值,也是该选项的缺省值。(4)堆栈类型:•堆栈类型的值主要影响伪指令.STARTUP所生成的指令序列。该选项有二个可选值:NEARSTACK和FARSTACK。其中:NEARSTACK是该选项的缺省堆栈类型。–NEARSTACK——堆栈段和数据段是同一段;–FARSTACK——堆
栈段和数据段是不同的段,且堆栈不在段组DGROUP中。例:.MODELSMALL,C,OS_DOS,FARSTACK2.处理器选择伪指令.8086和.8087可用来汇编8086/8088处理器和8087协处理器的指令,这是
缺省模式。.286、.286C、.286P、.287可用来汇编286系列微处理器的指令。.386、.386C、.386P、.387可用来汇编386系列微处理器的指令。.NO87取消使用协处理器指令。.486、.48
6C、.486P可用来汇编486系列微处理器的指令。.586、.586C、.586P可用来汇编Pentium系列微处理器的指令。.686、.686P可用来汇编PentiumPro系列微处理器的指令。.MMX可用来汇编MMX指令。.MMX和.686、.686P是MASM6.12引入的
。.K3D可用来汇编AMD处理器的3D指令,是MASM6.13引入的。.XMM可用来汇编SSE指令和SSE2指令,是MASM6.15引入的。注意:80386以上处理器中,如果处理器选择伪指令放在.MODEL伪指令前面,那么段将定义成32位的段。如果希望处理器使用16位的段,则应在.MO
DEL伪指令后面使用处理器选择伪指令。3.段名的缺省名使用简化的段定义伪指令时,每个段都有一个缺省名。–在中内存模式和大内存模式时,.CODE伪指令表示的缺省段名为name_TEXT,即name是这个段名的可变部分,当程序模块有一个具体名字时,name就表示这个名字。–.DATA、.CON
ST、.DATA?、.STACK定义的段内数据存放在一个叫DGROUP的段组中,各个段内的偏移地址均以这个起始地址为起点,而不依本段内的段地址为起点。–.FARDATA或.FARDATA?伪指令使用的缺省名在各种模
式下可以替换,它们定义的段内数据不放在任何段中,属于远程数据。内存模式段定义伪指令段名定位组合类别组名Small.CODE.DATA.CONST.DATA?.STACK_TEXT_DATACONST_BSSST
ACKWORDWORDWORDWORDPARAPUBLICPUBLICPUBLICPUBLICSTACK'CODE''DATA''CONST''BSS''STACK'DGROUPDGROUPDGROUPDGROUP4.等价名的使用•MASM5.
0中规定了几个等价名代替真实名。可以用@代替简化段定义伪指令前面的小数点。–@CODE代表.CODE定义的段名;–@FARDATA代表.FARDATA定义的段名;–@DATA代表.DATA、.DATA?、.CONST和
.STACK共享的组段名。例:ASSUMEES:@FARDATA;ES为远程数据段地址MOVAX,@DATAMOVDS,AX;DS为DGROUP段组段地址MOVAX,@FARDATAMOVES,AX5.段序定义伪指令•MASM可以按照源程序中各个段出现的次序来排列目标文件中各段的
先后次序,也可以按照段名的字母顺序来排列次序。缺省情况是按照段出现的次序来排列,可以定义段序:①.ALHPA:按照字母顺序对段排序。②.SEG:按照段出现的顺序对段排序。完整段定义格式中,默认按此顺序。③.DOSSEG:
按照DOS定义的标准段序对段排序,顺序为:代码段、数据段、堆栈段。采用.MODEL伪指令的简化段定义格式默认按此顺序。三、使用简化段定义的程序框架(1)EXE标准程序框架•汇编语言源程序经过汇编和连接后生成可执行文件(.exe)。操作系统为程序建立了一个程序段前缀
区PSP,其长度为256个字节,主要用于存放用户程序的有关信息,如文件名、文件长度等。而在偏移100H处才装入程序本身。EXE程序加载要重新定位:1)DS和ES指向PSP段地址,而不是程序的数据段和附加段,所以需在程序中根据实际数据段
改变DS和ES;2)CS:IP和SS:SP是由连接程序确定的值,指向程序的代码段和堆栈段。如果不指定堆栈段,则SS=PSP段地址,SP=100H,堆栈段占用PSP中的部分区域。例.MODELSMALL;小内
存模式.586;可汇编并运行586指令.STACK100H;256字节堆栈.DATAMSGDB'Welcome$';要写的信息.CODE.STARTUPMOVDX,OFFSETMSG;信息存储区首地址送DXMOVAH,9HINT21H;DOS写功能
调用,在屏幕显示变量MSG内容'Welcome‘.EXIT0;返回END(2).COM格式的程序框架•.COM程序是一种将代码、数据和堆栈段合一的结构紧凑的程序,所有的段都在一个逻辑段内,不超过64KB。
在程序中采用.MODELTINY模式定义语句即可生成COM结构的程序。COM文件存储在磁盘上是主存的完全影像,不包含重新定位的加载信息,加载速度更快,占用的磁盘空间更少。COM程序加载后:1)所有段地址都指向PSP的段地址;2)程序执行起点是PSP后的第一条指令,既IP=100H;也就是
说,COM程序的第一条指令必须是可执行指令,即程序的起始执行处是程序头。3)堆栈区设在段尾(通常为FFFEH),栈底的内容置为0000字。例子.MODELTINY;采用微型模式.CODE;只有一个段,没有数据段和附加段.STARTUP;等效于ORG100H,汇编程
序自动产生MOVDX,OFFSETSTRING1;显示提示信息MOVAH,9INT21HMOVAH,01H;等待按键INT21HMOVDX,OFFSETSTRING2;显示结束信息MOVAH,9INT21H.EXIT0STRING1DB'PRESSANYKEYTOCO
NTINUE!$'STRING2DB10,13,'PROGRAMRUNCOMPLETE!$'END一、重复汇编伪指令(1)按参数值重复伪指令REPEAT:按设定的重复次数连续重复汇编重复体的语句,其格式为:REPEAT重复次数;重复开始重复体ENDM;重复结束例:定义26个大写字母
CHAR=’A‘A_ZTABLEEQUTHISBYTE;A_ZTABLE用于为字符串指明首地址REPEAT26DBCHARCHAR=CHAR十lENDM(2)按参数个数重复伪指令FOR:每一次的重复把重复体中的形参用一个实参取代FOR形参,<实参表>重复体ENDM例:要保护常
用寄存器,可用如下伪指令:FORREGAD,<AX,BX,CX,DX>PUSHREGADENDM5.3.2重复汇编和条件汇编伪指令(3)按参数字符个数重复伪指令FORC:每一次的重复把重复体中的形参用一个字符取代。FORC形参,字符串;或FO
RC形参,<字符串>重复体ENDM例:要恢复常用寄存器可用如下伪指令:FORCREGAD,<DCBA>POPREGAD&X;&表示依次用字符串中的DCBA代替REGAD再与X连接ENDM重复汇编伪指令续条件汇编伪指令的一般格式是:IFxx表达式;条件满足,汇编分文语句体
1分支语句体1[ELSE;条件不满足,汇编分支语句体2分支语句体2]ENDIF;条件汇编结束例:定义一个元素个数不超过100的数组PDATAMACRONUMIFNUMLTL00;如果NUM<100,则汇编如下语句DBNUMDUP(?)ELSE;否则,汇编如下语句DB100DUP(?)ENDI
FENDM如果实参小于等于100,则汇编DBNUMDUP(?)语句;否则汇编DB100DUP(?)。例如:PDATA12;第一次宏调用DB12DUP(?);宏第一次汇编结果(不是列表文件的宏展开形式)PDATA102;第二次宏调用DB100DUP(?);第二次宏汇编结
果二.条件汇编伪指令例如,定义名为PEOPLE的结构如下:PEOPLESTRUCTPNAMEDB10DUP(?)PSEXDB'M'PAGEDB0PEOPLEENDSONEPEOPLE{'ZhangFei',,20}
TWOPEOPLE{'ZhaoYun','F',30}THEYPEOPLE10DUP({})例:MOVONE.PAGE,18;ONE变量的PAGE字段的值为18MOVDI,OFFSETTHEY;取结构数组首址MOVAL,1MOVCX,LENGTHTHEY;取结构
数组元素个数LP:MOV[DI].PAGE,AL;依次向PAGE字段传送数值INCAL;修改数值ADDDI,TYPETHEY;修改指针,即DI+12LOOPLP5.3.3结构定义伪指令