第4章 汇编语言程序设计 4.1 汇编语言概述 4.2 汇编语言源程序格式 4.3 汇编语言程序设计 4.4 DOS功能调用
4.1 汇编语言概述 汇编语言是用助记符表示指令的,地址、数据也可以用符号表示,与机器语言相比,编写、阅读和修改都比较方便。 4.1 汇编语言概述 汇编语言是用助记符表示指令的,地址、数据也可以用符号表示,与机器语言相比,编写、阅读和修改都比较方便。 用汇编语言编写的程序叫做汇编语言源程序,在计算机执行之前,需要翻译成目标程序。这个翻译过程叫做汇编。完成汇编的程序软件叫汇编程序,使用较广泛的有Microsoft公司开发的宏汇编程序MASM。 此外,MASM还能根据用户的要求分配存储区域、检查源程序的语法错误等。 目标文件虽然是二进制文件,但还不能直接在计算机上运行,必须通过连接程序(LINK程序)将目标程序与库文件或其他文件连接起来形成可执行文件,才能在机器上运行。
4.2 汇编语言源程序格式 汇编语言源程序结构采用分段式结构。 4.2 汇编语言源程序格式 汇编语言源程序结构采用分段式结构。 一个汇编语言源程序由若干段组成,一般有数据段、代码段、扩展段和堆栈段四种类型,源程序可以根据实际需要来确定段的数目。 数据段、扩展段一般用来存放与程序有关的数据。 代码段存放程序的指令代码。 堆栈段为程序中堆栈操作提供存储空间。 本节首先介绍汇编语言的语句格式、以及伪指令和使用方法,最后给出完整的汇编语言源程序格式。
4.2.1 汇编语言的语句格式 1.汇编语言的语句分类 2.汇编语言语句的格式
1. 汇编语言的语句分类 汇编语言有三种基本语句:指令语句、伪指令语句和宏指令语句。 指令语句是指在汇编时产生目标代码对应着机器某种操作的语句,每条指令语句都对应着CPU的一条机器指令。 伪指令语句不产生任何目标代码,它是一种指示性语句,只是指示汇编程序如何进行汇编,只有在汇编和连接时才起作用。 宏指令语句是以宏名定义的一段指令序列,是一般性指令语句的扩展。在汇编时,凡是出现宏指令语句的地方全部用其对应指令序列的目标代码代替。
2. 汇编语言语句的格式 指令语句的格式为: [标号:] 助记符号 [操作数] [;注释] 伪指令语句的格式为: [标号:] 助记符号 [操作数] [;注释] 伪指令语句的格式为: [名字] 定义符号 [参数][,…参数][;注释]
1)标号、名字 标号、名字代表该语句的存储器地址。标号后面要紧跟一个冒号“:” 。标号在一些指令中充当操作数,用来表示转移地址。名字可以是变量名、段名、过程名等。 标号和名字均应使用合法的标识符,在汇编语言中标识符的命名规则为: ①标识符的第一个字符必须是字母、问号?、@或下划线四者之一; ②从第二个字符开始可以是字母、问号?、@、下划线或数字; ③标识符不能是保留字(例如MOV、STACK)。 建议在给标识符命名时,应使标识符命名与它代表的内容相符。
2)助记符、定义符 指令语句中的助记符,规定了该指令语句的操作。例如ADD、XOR等。 伪指令语句中的定义符对应于8086宏汇编中提供的伪操作功能。
3)操作数 根据不同的指令,可能是单操作数或双操作数,也可能不带操作数。 伪指令语句中的操作数可以是一个或多个,操作数之间用逗号隔开。 操作数可以是常量、变量、标号、寄存器和表达式等。
(1)常量 常量是指令中出现的固定不变的值。 可分为数值常量和字符常量两种。 数值常量允许使用二进制、十进制、十六进制数,但要注意应以B、D、H字符结尾。 十六进制数如果以字母开头,则必须在该数前面加0,以区别于标识符,如0F5H。 ASCII码常数可将字符放在单引号内,如‘A’。
(2)变量 变量通常是指存放在某些存储单元中的值,这些值是可变的。可以用不同的寻址方式对其存取。变量具有如下三种属性: 段属性:指变量所在段的段基址。 偏移量属性:指变量单元地址与段的起始地址之间的地址偏移量。 类型属性:是指变量所占存储单元的字节数大小。类型有字节(BYTE) 、字(WORD)、双字(DWORD)等。
(3)标号 标号有三种属性: 段属性:定义标号的程序段的段基址,当程序中引用一个标号时,该标号的段地址应在CS寄存器中。 偏移量属性:标号所在段的起始地址与定义标号的地址之间的字节数 。 标号的类型属性:NEAR和FAR。NEAR标号可以在段内被引用,它所代表的地址指针为两个字节;FAR标号可以跨段引用,它所代表的地址指针为四个字节。
(4)寄存器 操作数部分是寄存器名,如AX、BX、SI等。
(5)表达式 表达式是由常数、变量、操作符和运算符组成。 有三种运算符(算术运算符、逻辑运算符、关系运算符)和两种操作符(分析操作符、合成操作符)。 表达式分为数值表达式和地址表达式。 数值表达式只产生数值结果。 地址表达式不是单纯的数值,而是具有不同属性的存储器地址变量或标号,属性包括:段、偏移量和类型。
①算术运算符 包括:+(加)、-(减)、×(乘)、/(除)、MOD(取模)等。 算术运算符可用于数值表达式,运算结果是一个数值。 在地址表达式中,只能使用“+”、“-”运算符。
②逻辑运算符 包括:AND(与)、OR(或)、XOR(异或)、NOT(非)。 注意:逻辑运算符只适用于数字操作,对存储器地址操作不适用。 例: MOV AX,789AH XOR 000FH 该指令实际等价于 MOV AX,7895H。
③关系运算符 包括:EQ(等于)、NE(不等于)、LT(小于)、GT(大于)、LE(小于等于)、GE(大于等于)。 关系运算符所连接的两个操作数,必须是数字或是同一段内的存储器地址。 运算结果为数字值。 当关系不成立,则结果为0; 当关系成立,则结果为全1。 例:MOV AL,5 NE 2;关系成立,故(AL)=0FFH MOV AL,5 LT 2;关系不成立,故(AL)=00H
④分析运算符 a)取地址偏移量算符OFFSET 格式:OFFSET 变量或标号 例: MOV SI,OFFSET BUF 该指令等价于LEA SI,BUF。 但要注意OFFSET后面只能是变量或标号。
④分析运算符(续) b)取段基址算符SEG 格式:SEG 变量或标号 例:MOV AX,SEG BUF 该指令执行后,将BUF 所在段的段基址送入寄存器AX。
④分析运算符(续) c)取类型算符TYPE 格式:TYPE 变量或标号 该算符返回的结果为一数值。 TYPE返回值 变量类型 标号类型 1 2 3 BYTE WORD DWORD -1 -2 NEAR FAR
④分析运算符(续) d)取变量单元数 LENGTH 格式:LENGTH 变量 如果一个变量已用重复操作符DUP说明其变量的个数,则利用LENGTH算符可以得到这个变量的个数。 如果未用DUP说明,则得到结果总为1。
④分析运算符(续) e)取变量字节数 SIZE 格式:SIZE 变量 如果一个变量已用重复操作符DUP说明其变量的个数,则利用SIZE算符可以得到这个变量的字节总数。 如果未用DUP说明,则得到的结果和TYPE算符所得结果相同。
⑤合成运算符 利用合成运算符可对变量、标号或存储器操作数的类型属性进行修改。 类型设置运算符PTR 格式:类型 PTR 表达式 其中类型可以是BYTE、WORD、DWORD、NEAR、FAR。该算符强制设置表达式类型为算符前的规定类型。 例: MOV BYTE PTR [SI], 200 定义类型算符THIS 格式:THIS 类型 该算符的功能是将类型符后面的类型属性赋予当前的存储单元。
4)注释 注释由分号“;”引导,用来说明一段程序、一条或几条指令的功能,使程序便于阅读。 汇编程序对注释不进行汇编。
4.2.2 伪指令 伪指令是给汇编程序的控制命令,在汇编过程中由汇编程序进行处理,例如定义变量、常量,分配存储区、定义段以及定义过程。 4.2.2 伪指令 伪指令是给汇编程序的控制命令,在汇编过程中由汇编程序进行处理,例如定义变量、常量,分配存储区、定义段以及定义过程。 翻译成目标程序后,这些伪指令就不存在了。
1.符号定义伪指令 符号定义伪指令用来给一个符号重新命名,或定义新的类型属性等。这些符号包括汇编语言中所用的变量名、标号名、过程名、寄存器名以及指令的助记符等。符号定义伪指令有EQU和=两种。 1)等价伪指令 格式:符号名 EQU 表达式 例: A EQU 5*3+2 利用EQU伪指令,可以用一个名字代表一个数值。如该数值在程序中多次被引用,这种方法可以使程序更加简洁,并且将来修改数值时,只要修改一处,而不必修改多处,提高了修改的效率。 利用EQU伪指令,也可以用一个较短的名字来代表一个较长的名字。 需要注意的是,EQU伪操作不能对同一个符号重复定义。 2)等号伪指令 格式:符号名 = 表达式 等号伪指令主要用来定义符号常量。其功能与EQU类似,而与EQU的唯一区别是它能对符号进行再定义。
2.数据定义伪指令 数据定义伪指令用来定义一个变量,为变量分配存储空间,赋初值等。 格式:[变量名] 伪指令 表达式[,表达式] 格式:[变量名] 伪指令 表达式[,表达式] 变量名字段为可选项,可有可无。 表达式可以不止一个,但相互之间应以逗号分开。 数据定义伪指令: 用DB定义的变量类型为字节(BYTE); 用DW定义的变量类型为字(WORD); 用DD定义的变量类型为双字(DWORD); 用DQ定义的变量类型为四字(QWORD); 用DT定义的变量类型为10个字节(TBYTE)。
2.数据定义伪指令(续) 表达式可以是以下几种: 常量或常量表达式。 ASCII码字节或字节串。 问号“?”表示初值未确定,常用来预留存储空间。 重复子句DUP格式为:N DUP (表达式) 其中N为重复次数,DUP为重复保留字,括号内的表达式为重复的内容。 地址表达式。即用变量名来表示的变量地址。
3.段定义伪指令 汇编语言源程序的结构是分段编写的。一个汇编语言源程序由若干个逻辑段组成,所有的指令、变量分别存放在各个逻辑段中。 段定义伪指令用来定义汇编语言源程序的逻辑段。常用的段定义伪指令有SEGMENT、ENDS和ASSUME等。
1)伪指令SEGMENT/ENDS 格式:段名 SEGEMNT [定位方式] [组合方式] [‘类别’] … 段名 ENDS 省略号部分,对于数据段、扩展段和堆栈段来说,一般是存储单元的定义、分配等伪指令;对于代码段来说,一般完成程序功能的指令语句和伪指令语句。 段名是程序员为该段起的名字,不可省略。 定位方式、组合方式、‘类别’是赋给段名的属性,用方括号括起来的项可以缺省。
2)伪指令ASSUME 通过建立段与段寄存器之间的对应关系,来明确源程序中的逻辑段与物理段之间的关系。 其中段寄存器名必须是CS、DS、ES、SS中的一个,段名必须是由SEGMENT和 ENDS伪指令定义的段名。 ASSUME伪指令只指定所定义的段和段寄存器的对应关系,并不能将段地址装入段寄存器中。 数据段、扩展段、堆栈段寄存器的初值应该在代码段中由程序写入,代码段CS寄存器的初值由系统自动装入。
3)当前汇编地址计数器和定位伪指令ORG 汇编地址计数器保存当前正在被汇编程序翻译的指令或伪指令的地址。用符号$来代表当前汇编地址计数器中的值。 定位伪指令ORG可以设置当前汇编地址计数器中的值。 格式:ORG 数值表达式 例:DSEG SEGMENT ORG 10H BUF DB ‘1234’ ORG $+5 NUM DW 50 DSEG ENDS BUF变量在DSEG段中的偏移地址为10H,第二个ORG语句是在当前汇编地址计数器值上再加5,使$的值变为14H+5=19H。故NUM的偏移地址为19H。
4.过程定义伪指令 格式: 过程名 PROC [NEAR/FAR] … 过程名 ENDP 如没有指明类型,则默认为NEAR类型。 PROC和ENDP必须成对出现。 当一个程序段被定义为过程后,在其它地方就可以通过CALL指令来调用这段程序。
4.2.3 汇编语言源程序的结构 例:两数求和的程序段 DSEG SEGMENT ‘DATA’ ;定义数据段 汇编语言程序的结构是分段结构形式,一个汇编语言源程序由若干段组成,每个段以SEGMENT开始,以ENDS结束。 整个源程序以END结束。 每个段均有若干行指令,每一条指令占一行。 例:两数求和的程序段 DSEG SEGMENT ‘DATA’ ;定义数据段 DATA1 DB 15H;被加数 SUM DB 00H;和 DSEG ENDS;数据段结束 CSEG SEGMENT ‘CODE’ ;定义代码段 ASSUME CS:CSEG,DS:DSEG START: MOV AX, DSEG MOV DS, AX;装入数据段DS初值 MOV AL, DATA1;被加数送AL ADD AL, 12H; (AL)+12H →AL MOV SUM, AL;和送SUM HLT;暂停指令 CSEG ENDS;代码段结束 END START;源程序结束
4.3 汇编语言程序设计 4.3.1 程序设计的基本步骤 4.3.2 顺序结构 4.3.3 分支结构 4.3.4 循环结构 4.3 汇编语言程序设计 4.3.1 程序设计的基本步骤 4.3.2 顺序结构 4.3.3 分支结构 4.3.4 循环结构 4.3.5 子程序结构
4.3.1 程序设计的基本步骤 分析问题,建立数学模型 确定算法 绘制流程图 分配存储器及寄存器 编制程序 调试程序 整理开发文档、投入使用 程序的基本结构有三种形式:顺序结构、分支结构和循环结构。
4.3.2 顺序结构 顺序程序是指程序在执行时是完全按照指令的存放顺序从第一条开始逐条执行,直到最后一条指令为止。 4.3.2 顺序结构 顺序程序是指程序在执行时是完全按照指令的存放顺序从第一条开始逐条执行,直到最后一条指令为止。 用顺序程序能较好地完成一些基本功能,例如数据的传送和交接、查找和算术运算等。 它是构成复杂程序的基础。
顺序结构程序示例 设内存单元DATA存放一字节无符号数,编程将其拆成二个一位十六进制数,HEX单元存放低位十六进制数,HEX+1单元存放高位十六进制数。 DSEG SEGMENT DATA DB 8AH HEX DB 0,0 DSEG ENDS SSEG SEGMENT STACK STK DB 100 DUP(?) SSEG ENDS CSEG SEGMENT ASSUME CS:CSEG,DS:DSEG,SS:SSEG START: MOV AX,DSEG MOV DS,AX MOV AL,DATA;无符号数送AL MOV AH,AL;保存副本到AH AND AL,0FH ;屏蔽高四位 MOV HEX,AL;保存低四位 AND AH,0F0H ;屏蔽低四位 MOV CL,4 SHR AH,CL;右移四位 MOV HEX+1,AH;保存高四位 MOV AH,4CH INT 21H ;返回操作系统 CSEG ENDS END START
4.3.3 分支结构 在很多实际问题中,都是根据不同的情况进行不同的处理。这种思想体现在程序设计中,就是根据不同条件而跳到不同的程序段去执行,这就构成了分支程序。 在汇编语言程序设计中,跳跃是通过条件转移指令来实现的。
分支结构程序示例 设内存中有三个互不相等的有符号字数据,分别存放在X、Y、Z字单元中,编程将其中最小值存入MIN单元。 DSEG SEGMENT X DW 4321H Y DW 7658H Z DW 9B00H MIN DW ? DSEG ENDS SSEG SEGMENT STACK STK DB 100 DUP(?) SSEG ENDS CSEG SEGMENT ASSUME CS:CSEG,DS:DSEG,SS:SSEG START:MOV AX,DSEG MOV DS,AX MOV AX,X CMP AX,Y JL NEXT MOV AX,Y NEXT: CMP AX,Z JL DONE MOV AX,Z DONE: MOV MIN,AX MOV AH,4CH INT 21H CSEG ENDS END START
4.3.4 循环结构 在程序设计中,经常遇到一个程序段需要多次重复执行。对这类问题采用循环程序结构,可以使程序代码缩短,并节省内存。 4.3.4 循环结构 在程序设计中,经常遇到一个程序段需要多次重复执行。对这类问题采用循环程序结构,可以使程序代码缩短,并节省内存。 循环程序有两个基本结构:一种是先处理后判断结构,另一种是先判断后处理结构。 b) 先判断后处理结构 a) 先处理后判断结构
4.3.4 循环结构(续) 循环程序分四部分: 设置循环初值 循环体 修改部分 循环控制部分 结束处理部分
循环结构程序示例1 试编程统计由DATA单元开始的数据块中能被3整除的数的个数。结果存于COUNT单元中。(设数据块中共有10个无符号数) 分析:可以采用除法指令,对待判断的无符号数做除3操作,然后检查余数是否为零,若为零,则该数能被3整除。
循环结构程序示例1流程图
循环结构程序示例1源程序 DSEG SEGMENT DATA DB 41,9,33H,0F0H,32,0AH,0FFH,99,68,23H COUNT DW ? DSEG ENDS SSEG SEGMENT STACK STK DB 100 DUP (?) SSEG ENDS CSEG SEGMENT ASSUME DS:DSEG,SS:SSEG,CS:CSEG START: MOV AX,DSEG MOV DS,AX LEA SI,DATA MOV CX,10 MOV DX,0 MOV BL,3 LP: MOV AL,[SI] MOV AH,0 DIV BL AND AH,AH JNZ NEXT INC DX NEXT: INC SI LOOP LP MOV COUNT,DX MOV AH,4CH INT 21H CSEG ENDS END START
循环结构程序示例2 试编程统计DA1字单元中二进制数据中含1的个数,结果存于DA2单元中。 分析:可以利用移位指令,将待判断的字数据一位一位地移到进位位中,然后判断进位位是1还是0,以此实现对二进制数据中含1的个数统计。
循环结构程序示例2流程图
循环结构程序示例2源程序 DSEG SEGMENT DA1 DW 3F28H DA2 DB ? DSEG ENDS SSEG SEGMENT STACK STK DB 100 DUP (?) SSEG ENDS CSEG SEGMENT ASSUME DS:DSEG,SS:SSEG,CS:CSEG START: MOV AX,DSEG MOV DS,AX XOR BL,BL MOV AX,DA1 LP: AND AX,AX JZ DONE SHL AX,1 JNC LP INC BL JMP LP DONE: MOV DA2,BL MOV AH,4CH INT 21H CSEG ENDS END START
4.3.5 子程序结构 在编写程序时,经常在不同的位置或不同的程序段中存在相同语句串,可以将它们抽取出来,组成子程序,供其它程序调用,调用子程序的程序被称为主程序。 不但使主程序结构清晰,而且节省了内存空间。
编写子程序应注意: 主程序和子程序之间的信息交换主要通过参数的传递来实现。参数传递的方法有三种: 寄存器传递法 存储器传递法 堆栈传递法。 注意保护和恢复现场。所谓现场,就是指调用程序当前CPU状态,包括标志寄存器、通用寄存器、段寄存器以及指令指针寄存器的内容。保护和恢复的操作一般在子程序中进行,进入子程序后,就应该把子程序中所使用到的寄存器内容保存在堆栈中,而在子程序返回主程序之前根据堆栈中的内容恢复原来的状态。
子程序结构示例1 编制程序实现两数据块的传送。 子程序的入口参数SI和DI分别指向源数据块和目的数据块的首地址,CX用来存放数据块的长度。本例采用寄存器传递参数的方法来完成主程序与子程序之间的传递参数。
子程序结构示例1源程序 ;子程序名:MOVSTR ;功能:完成数据块的传送 ;入口参数:SI←源数据块的首地址 ; DI←目的数据块的首地址 DSEG SEGMENT SOURCE DB d1,d2, …..,dn LENT EQU $-SOURCE DEST DB LENT DUP(?) DSEG ENDS SSEG SEGMENT STACK STK DB 100 DUP (?) SSEG ENDS CSEG SEGMENT ASSUME DS:DSEG,SS:SSEG,CS:CSEG START: MOV AX,DSEG MOV DS,AX LEA SI,SOURCE;源数据块的首地址送SI LEA DI,DEST;目的数据块的首地址送DI MOV CX,LENT;数据块的长度送CX CALL MOVSTR MOV AH,4CH INT 21H ;子程序名:MOVSTR ;功能:完成数据块的传送 ;入口参数:SI←源数据块的首地址 ; DI←目的数据块的首地址 ; CX←数据块的长度 MOVSTR PROC NEAR PUSH AX LP1: MOV AL,[SI] MOV [DI],AL INC SI INC DI LOOP LP1 POP AX RET MOVSTR ENDP CSEG ENDS END START
子程序结构示例2 将内存中的两个数组的对应单元求和,其结果存放到另一个数组中,要求求和部分由子程序完成。 需要注意,由于CALL指令将返回地址存放在堆栈的顶部,故在子程序中,从堆栈中取参数,不能使用POP指令,应该使用MOV指令直接到堆栈中取出参数。
子程序结构示例2源程序 SUM PROC NEAR PUSH BP MOV BP,SP MOV AX,[BP+2] DSEG SEGMENT A1 DW 100,300,28,40,55,121,39,21,39,165 A2 DW 20,102,18,33,65,141,1,155,18,120 A3 DW 10 DUP (0) DSEG ENDS SSEG SEGMENT STACK STK DB 100 DUP (?) SSEG ENDS CSEG SEGMENT ASSUME DS:DSEG,SS:SSEG,CS:CSEG START:MOV AX,DSEG MOV DS,AX MOV CX,10 MOV SI,OFFSET A1 MOV DI,OFFSET A2 MOV BX,OFFSET A3 LOP: PUSH WORD PTR [SI] PUSH WORD PTR [DI] CALL SUM MOV [BX],AX ADD BX,2 ADD SI,2 ADD DI,2 LOOP LOP MOV AH,4CH INT 21H SUM PROC NEAR PUSH BP MOV BP,SP MOV AX,[BP+2] ADD AX,[BP+4] POP BP RET SUM ENDP CSEG ENDS END START
4.4 DOS功能调用 DOS(Disk Operation System) 和BIOS(Basic Input and Output System)为用户提供两组系统服务程序。用户程序可以调用这些系统服务程序。 DOS提供若干功能调用。包括基本输入/输出管理、内存储器读/写管理、磁盘文件的读/写管理、时间和日期的设置功能。 BIOS在较低层次上为用户提供一组I/O程序,要求用户对硬件有一定的了解,但也不要求用户直接控制外设。BIOS驻留在ROM中,独立于操作系统。 用户通过软中断指令INT n去调用DOS和BIOS中的服务程序来访问系统。
4.4.1 系统功能调用的方法 每执行一次INT n就调用相应的中断服务程序系统。当n=5~1FH,调用BIOS中的服务程序,当n=20~3FH时,调用DOS中的服务程序。 INT 21H是一个具有多个子功能的中断服务程序,这些子功能的编号称为功能号。INT 21H一般称为系统功能调用。 调用步骤: 将入口参数送到指定寄存器中。 将功能号送入AH寄存器中。 执行中断指令INT 21H。 有些中断服务子程序不需入口参数。
4.4.2 常用的系统功能调用 1.读取键盘单个字符并回显(01H功能) 调用方式: MOV AH,1;子功能号送AH INT 21H 4.4.2 常用的系统功能调用 1.读取键盘单个字符并回显(01H功能) 调用方式: MOV AH,1;子功能号送AH INT 21H 说明:该调用没有入口参数,执行时,系统扫描键盘,等到键盘按下,先检查是否是CTRL-BREAK键,如是则退出命令执行,否则将按下键对应ASCII码送入AL寄存器,并在屏幕上显示该字符。
4.4.2 常用的系统功能调用(续) 2.在屏幕上输出单个字符(02H功能) 调用方式: MOV AH,2;子功能号送AH 4.4.2 常用的系统功能调用(续) 2.在屏幕上输出单个字符(02H功能) 调用方式: MOV AH,2;子功能号送AH MOV DL,’A’ INT 21H;将字符’A’在屏幕上显示出来 说明:该调用无出口参数,入口参数(待显示字符的ASCII码)送DL,如DL中的字符为CTRL-BREAK,则终止程序执行。
4.4.2 常用的系统功能调用(续) 3.在打印装置上输出单个字符(05H功能) 调用方式: MOV AH,5;子功能号送AH 4.4.2 常用的系统功能调用(续) 3.在打印装置上输出单个字符(05H功能) 调用方式: MOV AH,5;子功能号送AH MOV DL,’A’ INT 21H;将字符’A’在打印机上打印出来
4.4.2 常用的系统功能调用(续) 4.在屏幕上输出字符串(09H功能) 功能:在输出设备上显示一个以$为结束标志的字符串。 4.4.2 常用的系统功能调用(续) 4.在屏幕上输出字符串(09H功能) 功能:在输出设备上显示一个以$为结束标志的字符串。 入口参数:DS:DX指向一个以$为结束标志的字符串。 例: BUF DB ‘WELCOME TO OUR SYSTEM$’ ….. MOV DX,OFFSET BUF MOV AH,9 INT 21H 运行后,在屏幕上显示 “WELCOME TO OUR SYSTEM”。
4.4.2 常用的系统功能调用(续) 5.字符串输入(0AH功能) 功能:将从键盘上输入的一串字符送到指定的内存缓冲区。 4.4.2 常用的系统功能调用(续) 5.字符串输入(0AH功能) 功能:将从键盘上输入的一串字符送到指定的内存缓冲区。 入口参数:DS:DX指向内存缓冲区。 缓冲区的第一个字节:放缓冲区能容纳的最大字符个数(1-255),不能为零。 缓冲区的第二个字节:是保留来填写实际输入的字符个数,由计算机自动填入。 缓冲区的第三字节开始,存放从键盘接收到的字符,最后结束字符串的回车符也包括在内。如实际键入的字符数少于定义的字节数,缓冲区内其余字节填零,若多于定义的字节数,则后来的输入字符丢掉并响铃。
字符串输入(0AH功能)示例 DSEG SEGMENT BUF DB 30 ;定义缓冲区的长度 DB ? ;保留为填入实际输入的字符个数 DB 30 DUP (?) ;定义30个字节存储空间,用以存放键入的字符 DSEG ENDS CSEG SEGMENT ….. LEA DX,BUF MOV AH,0AH INT 21H CSEG ENDS
4.4.2 常用的系统功能调用(续) 6.返回操作系统(4CH功能) 无入口参数。 功能:结束当前程序,返回操作系统。 调用方式: 4.4.2 常用的系统功能调用(续) 6.返回操作系统(4CH功能) 无入口参数。 功能:结束当前程序,返回操作系统。 调用方式: MOV AH ,4CH INT 21H