


单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第四章 汇编语言程序设计,汇编语言是利用指令的助记符、符号地址、标号来编写的语言,它是机器语言的符号表示,是较低级的语言利用汇编语言编写的程序称为源程序,指令系统中的每条指令都是构成源程序的基本语句但机器不能识别源程序,要通过汇编程序翻译成二进制代码的浮动目标程序,然后由连接程序将目标文件与库文件相连,最后得到可执行的程序,才可在机器上直接运行一个完整的汇编程序编写格式要包括以下几部分:段定义、段分配、设置段地址、返回DOS语句及程序结束,需要时加上过程调用1)汇编语言编写的原程序是分段的,要定义代码段、数据段、堆栈段,每段由段定义伪指令SEGMENT开始,ENDS结束,并赋予段名区分不同段段定义的基本格式如下:,段名 SEGMENT,段名 ENDS,原程序中至少有一个代码段,此时数据可放在代码段中;堆栈段如果不定义,由计算机自动分配段名可以自己定义,用字母和数字组成计算机识别不同的段由段分配伪指令ASSUME来完成段分配的格式为:,ASSUME CS:段名,DS:段名,SS:段名,ES:段名,(2)过程调用由伪指令PROCENDP实现,过程的调用格式如下(也可省略):,过程名 PROC FAR(NEAR);FAR表示远调用,NEAR表示近调用可缺省,过程名 ENDP,(3)若程序已经分别定义了数据段、堆栈段和附加段,主程序的开始要设置这些段的地址。
代码段的地址不能人为设置,由计算机分配堆栈段和数据段设置的具体语句为;,MOV AX,STACK ;送堆栈段地址,MOV SS,AX,MOV AX,DATA ;送数据段地址,MOV DS,AX,(4)程序执行完毕要返回DOS操作系统,有两种方式实现一种是在程序的开始部分编写如下语句:,PUSH DS,MOV AX,0,PUSH AX,将DS的内容及0作为段地址和偏移地址入栈,在程序结束时返回DOS以上三句语句必须写在堆栈段设置后面,否则堆栈段的设置使一些指令不起作用了第二种方法是在程序结束前使用DOS功能调用指令,如下所示:,MOV AX,4C00H,INT 21H,(5)全部源程序用END语句结尾,END后面可以加上程序执行起始的名称START,汇编程序遇见END语句就结束4.1 汇编语言程序格式,8086系统中常用的汇编程序是MASM6.X版本,MASM中可使用的语句分成两类:指令性语句和伪指令语句一、指令性语句,指令性语句与机器指令相对应,汇编程序可将它翻译成目标代码(机器指令代码)语句格式为:,标号:指令助记符 操作数,操作数 ;注释,标号表示本指令语句的符号地址,标号后面必须紧跟冒号“:”。
指令助记符是该语句的指令名称的代表符号,它指出指令的操作类型,汇编程序将其翻译成机器指令它是语句中的关键字,因此不可省略操作数表示参加本指令运算的数据,根据指令要求可以有一个或多个操作数,有的指令不需要操作数,多个操作数之间用逗号“,”隔开,操作数与指令助记符之间用空格隔开操作数可以是常数、变量、标号、寄存器名或表达式二、伪指令语句,伪指令语句没有对应的机器指令,汇编程序汇编源程序时对伪指令进行处理,它可完成数据定义,存储区分配,段定义,段分配,指示程序结束等功能伪指令语句的格式为:,名字 伪指令指示符 操作数,操作数 ;注释,名字是给伪指令取的名称,它用符号地址表示,名字后不允许带冒号“:”,名字可以省略伪指令中的名字通常是变量名、段名、过程名、符号名等伪指令指示符是汇编程序MASM规定的符号,常用的有变量定义语句(DB、DW),符号定义语句(EQU、),段定义语句(SEGMENT.ENDS),段分配语句(ASSUME),结构定义语句(STURC.ENDS),过程定义语句(PROR.ENDP)等类型,后面将详细说明操作数是由伪指令具体要求的,有的伪指令不允许带操作数,有的伪指令要求带多个操作数,多个操作数之间必须用逗号分开。
操作数可以是常数、变量、字符串、表达式等三、数据项,汇编语言中使用的操作数,可以是常数,寄存器、存储器、变量、标号或表达式,其中常数、变量和标号是三种基本数据项1常数,常数必须是固定值,没有属性,是确定的数据2变量,变量通常指存放在存储单元中的值,在程序运行中是可以修改的所有的变量都具有三个属性1)段值(SEGMENT)指变量所在段的段基址2)段内偏移地址(OFFSET):指变量地址与所在段首地址之间的地址偏移字节数3)类型(TYPE):变量的类型属性指变量中每个元素所包含的字节数,类型有:字节变量(BYTE)、宇变量(WORD)及双字变量(DWORD)等3标号,标号是可执行指令语句的地址的符号表示,它可作为转移指令的目标操作数,以确定程序转向的目标地址,它具有三个属性1)段值(SEGMENT):标号所在段的段基址2)段内偏移地址(OFFSET):标号地址与所在段的段首址之间的偏移地址字节数3)类型(TYPE):标号的类型属性指在转移指令中标号可转移的距离,也称距离属性类型NEAR,表示此标号为近标号,只能实现本代码段内转移或调用,类型FAR,表示此标号为远标号,可以作为其它代码段中的目标地址,实现段间转移或调用。
若标号后面紧跟冒号,表示隐含此标号距离属性为NEAR,也可用伪指令将此属性改为FAR4.2 MASM中的表达式,一、算术运算符,加、减、乘、除、MOD、SHL、SHR运算对象与运算结果都是整数二、逻辑运算符,逻辑运算符包括AND(与)、OR(或)、NOT(非),XOR(异或)4种,逻辑运算符是按位运算的,只能对常数进行运算,得到结果也是常数三、关系运算符,关系运算符包括EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)6种关系运算符的两个操作数必须是数据,或是同一段内的两个存储单元的地址进行关系运算的比较操作后,结果是一个数值,若结果为真,输出全是l,即,0FFH或0FFFFH若结果为假,输出全是0关系运算符一般与逻辑运算符组合起来使用四、数值返回运算符,1OFFSET,格式:OFFSET变量或标号,OFFSET返回标号或变量的偏移地址值2SEG,格式:SEG变量或标号,SEG用来取变量或标号的段基值3TYPE,格式:TYPE 变量或标号,TYPE加在变量前,返回变量的类型属性,TYPE加在标号前,返回标号的距离属性4LENGTH,格式:LENGTH 变量,当变量中使用DUP时,LENGTH返回此变量所包含的单元数,对其它变量则返回1。
5.SIZE,格式:SIZE变量,SIZE运算符加在变量前,返回该变量包含的总字节数SIZELENGTHTYPE,五、修改属性运算符,1.段操作符,格式:段前缀:变量或地址表达式,段前缀有段寄存器CS、DS、ES、SS后跟冒号“:”,用来表示某个变量或地址被修改到哪个段寄存器提供的段基址中2PTR,格式:类型/距离 PTR 变量或标号,其功能是将PTR左边的类属性赋给右边的变量或标号PTR本身并不分配存储单元,仅给已分配的存储单元赋予新的属性,以保证运算时操作数类型的匹配,常与类型BYTE、WORD、NEAR、FAR等连用3THIS,格式:变量/标号 EQU THIS 类型/距离,THIS的功能是将EQU THIS右边的类型/距离属性,赋给左边的变量/标号,该变量或标号的段地址和偏移地址与下一个存储单元的地址相同4SHORT,格式:SHORT标号,SHORT用来说明转移类指令中转向地址的属性,指出转向的目标地址与本指令之间的距离在128127之间,即限制在短转移范围内5HIGH和LOW,格式:H1GH/LOW变量或标号,HIGH和LOW称为字节分离运算符,对一个数或地址表达式,HIGH从中分离出高位字节,LOW分离出低位字节。
六、其它运算符,1圆括号(),圆括号用来改变运算符的优先级别,()中的运算符具有最高优先权2方括号 ,方括号主要用来表示地址表达式或多重变量的下标值3尖括号,及圆点,运算符在结构中专用,表示结构中的变量在预置结构付本时是否修改,修改成什么数值运算符在结构中专用,表示结构付本名与变量名连接在一起,作为预置的结构付本中的各个变量4MASK和WIDTH,MASK与WIDTH运算符在记录中专用WIDTH为记录名/字段名,运算后返回数值表示指定记录或字段的位的长度MASK为字段名,返回数值为8位/16位二进制数,对应指定字段的各位置“1”,其它位置“0”七、优先级,4.3 伪指令语句,一、数据定义语句,格式1:变量名 助记符 操作数,操作数 ;注释,格式2:变量名 助记符 n DUP(操作数,操作数);注释,功能:将操作数存入变量名指定的存储单元中,或者只分配存储空间不存入数据变量名它用符号表示,可以省略,作用与指令语句中的标号相同,但后面不跟冒号汇编程序汇编时将此变量的助记符后的第一个字节的偏移地址作为它的符号地址助记符所用伪指令助记符主要有:,DB:用来定义字节,表示每个操作数占用一个字节DW;用来定义字,表示每个操作数占用一个字。
DD:用来定义双字,表示每个操作数占用两个字DQ:用来定义四个字,表示每个操作数占用四个字DT:用来定义十个字节,表示每个操作数占用十个字节二、表达式赋值语句,表达式赋值语句有两种,赋值语句EQU和等号语句,它们均不占用内存1赋值语句EQU,格式:符号名 EQU 表达式,功能:用来给变量,标号,常数,指令,表达式等定义一个符号名,程序中用到EQU左边的变量、标号时可用右边的常数值或表达式代替,但一经定义在同一个程序模块中不能重新定义2等号语句,等号语句“”与EQU语句具有相同功能,区别仅在于EQU中左边的标号不允许重新定义,而用“”定义的语句允许重复定义三、段定义语句,1.段定义语句SEGMENTENDS,格式:段名 SEGMENT 定位类型 组合类型 分类名,逻辑段内容,段名 ENDS,功能:将一个逻辑段定义成一个整体段定义语句中的参数设置,可以增强伪指令语句的功能段定义语句允许嵌套设置,即一个逻辑段内再设置其它逻辑段,但不允许各个逻辑段相互交叉设置2.段分配语句(ASSUME),在8086/8088系统中存储器采用分段结构,各段容量64KB,用户可以设置多个逻辑段,但只允许4个逻辑段同时有效,段分配语句用来完成将逻辑段分别定义成代码段,数据段,堆栈段及附加段。
格式:ASSUME CS:段名,DS:段名,SS:段名,ES:段名,功能:定义4个逻辑段,指明段与段寄存器的关系ASSUME NOTHING 可以取消前面由ASSUME所指定的段寄存器例:两个16位无符号二进制数相乘DATA SEGMENT,D1 DW 1234H,D2 DW 5678H,P1 DD?,P2 DD?,DATA ENDS,STACK SEGMENT STACK STACK,DW 100 DUP(?),STACK ENDS,CODE SEGMENT,ASSUME CS:CODE,DS:DATA,SS:STACK,MAIN PROC FAR,START:MOV AX,STACK,MOV SS,AX,PUSH DS,SUB AX,AX,PUSH AX,MOV AX,DATA,MOV DS,AX,L1:MOV AX,D1,MUL D2,MOV BX,OFFSET P1,MOV BX,AX,MOV BX+2,DX,RET,MAIN ENDP,CODE ENDS,END START,四、过程定义语句,过程也称作子程序在主程序中,经常要用到一些程序段,程序段的功能和结构相同,仅有一些变量赋值不同,此时可以将这些程序段独立编写,用过程定义语句进行定义,然后在主程序中对它进行过程调用。