第4章汇编语言程序设计4.1汇编语言程序格式4.2MASM中的表达式4.3伪指令语句4.4DOS系统功能调用和BIOS中断调用4.5程序设计方法4.1汇编语言程序格式一、程序结构程序由语句构成,每条语句占一行。语句分两类:指令性语句(指令语句):能译成机器代码,完成一定的操作功能的语句。指示性语句(伪指令语句):为汇编程序在翻译汇编语言源程序时提供有关控制信息,没有相应的机器代码。指令性(指令)语句与指示性(伪指令)语句区别:程序经汇编、连接和装入内存后,在执行程序之前◢指示性语句的功能已经完成,故又称伪操作。◢而指令性语句的功能尚未完成,需控制CPU去执行才能完成。DATASEGMENT;伪指令语句BUF1DB34HBUF2DB2AHSUMDB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATA;指令语句MOVDS,AXMOVAL,BUF1ADDAL,BUF2MOVSUM,ALMOVAH,4CHINT21H;返回DOSCODEENDSENDSTART例:给出一个完整的汇编语言源程序完成两个字节数据相加。分段结构程序按段编写,与8086内存分段编址相对应。每段由伪操作SEGMENT开始、由ENDS结束。程序可由多个段构成,至少有一个代码段。程序最后为END结束语句,后跟一启动地址。启动地址指示程序开始执行的第一条语句。程序中设有返回DOS的功能。使程序执行完后返回DOS系统的命令接受状态。程序中用到内存操作数时应按操作数的寻址方式,给相应的段寄存器赋值。二、语句格式*指令助记符(操作码)不可以省略指令性语句标号:指令助记符操作数,操作数;注释格式:伪指令语句格式:名字伪指令指示符操作数,操作数;注释根据语句功能的不同,名字项可用来表示段名、变量名、标号、过程名等。•名字项用一个符号表示。对符号的规定:①由字符A~Z,a~z,0~9及符号@、$、下划线_等组成,最长31个字符,超出部分忽略。②不能用数字打头,以免与十六进制数相混。③不使用汇编程序中的保留字。(如指令的助记符等)④对定义的符号不区分大小写。但为便于记忆,名字的定义应该做到见名知意。1、名字项(提供符号地址)名字的两种主要形式:标号和变量标号:在代码段中定义,后面跟着冒号“:”,标号作为目标操作数经常在转移指令或调用指令中出现,用以表示转向地址。标号的三种属性:段属性(SEGMENT):标号所在段的段基值。偏移地址属性(OFFSET):标号所在地址与其所在段首址之间的偏移地址字节数。类型属性(TYPE):反应转移过程中标号可转移的距离,类型NEAR为近标号,只能实现段内转移;类型FAR为远标号,可实现段间转移。变量:变量在数据段、附加段或堆栈段中定义,后面不跟冒号。变量通常指存放在存储单元中的值,在程序运行中是可以修改的。变量的三种属性:段属性(SEGMENT):变量所在段的段基值。偏移地址属性(OFFSET):变量所在地址与其所在段首址之间的偏移地址字节数。类型属性(TYPE):指变量中每个元素所包含的字节数,类型有:字节变量(BYTE)、字变量(WORD)及双字变量(DWORD)等。*在同一个程序中,同样的标号或变量的定义只允许出现一次,否则汇编程序会指示出错。操作码可以是指令、伪指令中的助记符,用以指明操作的性质或功能。对于指令,汇编程序将其翻译成机器语言指令。MOVAX,100→B80001对于伪指令,汇编程序据其要求的功能进行处理。dataSEGMENT→data与一段基值对应stringDB‘Tsinghua’→string与一内存地址对应[标号][:]操作码[操作数,][;注释]名字项操作码助记符项操作数项注释项2、操作码项(不可省略)操作数给出参与操作的数或数所在的地方。操作数多于一个时,用逗号分开。操作数可以是常数、寄存器、存储器操作数、变量、标号、过程名或表达式(下一节介绍)等。[名字][:]操作码[操作数,][;注释]名字项操作码助记符项操作数项注释项3、操作数项常数给出具体的数据。可以是数字常量或字符常量。数字默认十进制,也可加D表示十进制数。如1234D,1234数字后加B表示二进制数。如1010B数字后加H表示十六进制数。如1234H字符常量,用单引号表示。如‘1234’汇编时,用字符对应的ASCII表示。如31H,32H,33H,34H例:data1DB12,34,56;十进制data2DB12H,34H,56H;十六进制MOVAL,‘G’;字符stringDB‘1234’;字符串A、B、C、D、E、F开头的十六进制数前面加0,与H结尾的标识符区别。如寄存器名AH、BH、CH、DH变量名abcdH等例:movAL,0AHmovAL,AHmovBX,0abcdH由分号引出,用来说明语句或程序的功能。汇编程序对分号后的内容不做处理。作用:①注释程序,增强程序可读性。②可放在语句最前,暂时注释某语句,调试程序用。例:、、、;MOVAH,2;显示提示信息;MOVDL,’A’;INT21H、、、4、注释项表达式表达式由运算对象(常量、标号、变量)及运算符组成。汇编程序对表达式进行运算后,得到一个确定的数值,再把这个数值汇编到指令中。运算结果可以是一个常数字,也可以是一个存储器的地址。故表达式分数字表达式、地址表达式。表达式是指令或伪操作的操作数;表达式中的操作符由汇编程序完成例MOVAX,12-4;MOVAX,8;数字表达式LEABX,[string+4];地址表达式4.2MASM中的表达式表达式中的操作符(参考P128表4-1)▲有以下几类:1).算术运算符(+、-、*、/、MOD)2).逻辑运算符(AND、OR、NOT、XOR)3).关系运算符(EQ、NE、GT、GE、LT、LE)真:FFFFH;假:04).数值返回操作符(SEG、OFFSET、TYPE、LENGTH、SIZE)5).修改属性操作(PTR)6).地址记数器($)例:1).算术运算符(+、-、*、/、MOD(取余数))MOVAX,6*8←MOVAX,482).逻辑运算符(AND、OR、NOT、XOR)MOVAX,80hOR70h←MOVAX,0F0h3).关系运算符(EQ、NE、GT、GE、LT、LE)真:FFFFH;假:0MOVAX,1GE2←MOVAX,0*表达式只是一个成份,不能单独构成语句。SEG取符号地址(变量或标号)的段地址例MOVAX,SEGyyOFFSET取符号地址(变量或标号)的偏移地址例MOVBX,OFFSETyybbSEGMENTyyDB6dup(?)bbENDSccSEGMENTASSUMECS:cc,DS:aa,ES:bbstart:CLDMOVAX,SEGyyMOVES,AXMOVDI,OFFSETyyMOVCX,6…….ccENDSENDstart4).数值返回操作符aaSEGMENTxxDB'Hello!’aaENDSbbSEGMENTyyDB6dup(?)bbENDSccSEGMENTASSUMECS:cc,DS:aa,ES:bbstart:CLDMOVAX,aaMOVDS,AXLEASI,xxMOVAX,SEGyyMOVES,AXMOVDI,OFFSETyyMOVCX,6REPMOVSBMOVAH,4CHINT21HccENDSENDstartD:\DEBUGhello1.exe-U;查看程序代码129F:0000FCCLD129F:0001B89D12MOVAX,129D129F:00048ED8MOVDS,AX129F:00068D360000LEASI,[0000]129F:000AB89E12MOVAX,129E129F:000D8EC0MOVES,AX129F:000FBF0000MOVDI,0000129F:0012B90600MOVCX,0006129F:0015F3REP129F:0016A4MOVSB129F:0017B44CMOVAH,4C129F:0019CD21INT21、、、、、、MOVAX,bbLEADI,yy注意:SEG、OFFSET只能对符号地址操作MOVAX,SEG[BX]MOVBX,OFFSET[SI]TYPE取符号地址(变量或标号)的类型属性例A1DB20H,30HA2DW0438HMOVAL,TYPEA1MOVAH,TYPEA2汇编时形成指令MOVAL,1MOVAH,2类型返回值变量DBDWDDDQ1248标号NEARFAR-1(FFH)-2(FEH)LENGTH取变量的长度属性例A1DW100DUP(?)A2DW1,2,3MOVCX,LENGTHA1MOVAH,LENGTHA2汇编时形成指令MOVCX,100;使用DUP时,返回此变量包含的单元数为100个字。MOVAH,1;对其他情况则返回1。SIZE取变量的总字节数SIZE=LENGTH*TYPE例A1DW100DUP(?)A2DW1,2,3MOVCX,SIZEA1MOVAH,SIZEA2汇编时形成指令MOVCX,200MOVAH,25).修改属性操作符PTR格式:类型/距离PTR变量或标号功能:将PTR左边的类型属性赋给右边的变量或标号。常用类型:BYTE、WORD、DWORD、NEAR、FAR例:MOVBYTEPTR[BX],10;[BX]10HMOVWORDPTR[BX],10;[BX],[BX+1]0010HES:,PTR,SHORT,HIGH/LOWHIGH和LOW——字节分离运算符格式:HIGH/LOW变量或标号功能:对一个数或地址表达式,HIGH从中分离出高位字节,LOW分离出低位字节。例:K1EQU0ABCDHK2EQU1234HMOVAH,HIGHK1MOVBL,LOWK2汇编时形成指令MOVAH,0ABHMOVBL,34H4.3伪指令语句一、定义符号的伪指令1、赋值伪指令EQU格式:符号名EQU需等值的表达式▲作用:用符号名等值指定的表达式.其中,表达式可以是任何有效的操作数,汇编时用语句中的表达式代替程序中符号所在的地方。▲应用:1.定义符号常量,方便修改程序。2.某表达式多次出现时,用等值伪操作可以方便编程。例:COUNTEQU5举例CONSTANTEQU256;将数256赋以符号名CONSTANTDATAEQUHEIGHT+12;HEIGHT为一标号,地址表达式赋以符号名DATAALPHAEQU7BETAEQUALPHA-2;这是一组赋值伪操作,把7-2=5赋以符号名BETAADDREQUVAR+BETA;将VAR+5赋以符号名ADDRBEQU[BP+8];变址引用赋以符号名BP8EQUDS:[BP+8];加段前缀的变址引用赋以符号名P82、等号伪指令“=”“=”与EQU相类似,也可作为赋值操作使用。它们之间的区别:EQU伪操作中的表达式名是不允许重复定义的,而“=”伪操作则允许重复定义。3、解除定义伪指令PURGE格式:PURGE符号1,符号2,…,符号N功能:解除指定符号的定义。解除符号定义后,可用EQU重新进行定义。例:Y1EQU7;定义PURGEY1;解除Y1EQU36;重新定义格式[变量名]类型助记符操作数[,操作数,...][;注释]▲用来定义程序中所用的内存操作数,并用变量与存储单元建立联系。变量名:符号地址类型助记符:指示内存操作数为字节、字、双字等。DB指示其后的操作数为字节类型DW…………………..为字类型DD.…………………为双字类型DQ(4个字)DT(10个字节)▲汇编程序按其类型分配内存单元数。操作数:指示内存操作数的内容顺序存入变量名指向的内存单元中。二、定义数据的伪指令定义数据伪指令应用:可以把其后跟着的数据存入指定的存储单元,形成初始化数据。或者只分配存储空间而并不存入确定的数值,形成未初始化数据空间。DW和DD伪指令还可存储地址。例1:定义赋初值的变量dataSEGMENTxxDB1,-1,0fcHyyDW1,-1,0fcHzzDD1,-1,0fcHdataEN