《汇编语言程序设计PPT课件》由会员分享,可在线阅读,更多相关《汇编语言程序设计PPT课件(207页珍藏版)》请在金锄头文库上搜索。
1、第三章第三章第三章第三章 第第第第4 4章章章章 汇编语言程序设计汇编语言程序设计汇编语言程序设计汇编语言程序设计第第4章章 汇编语言程序设计汇编语言程序设计4.1 概述4.2 汇编语言程序的格式与基本语法4.3 伪操作命令与宏指令4.4 DOS与BIOS的调用4.5 汇编语言程序设计主要内容:汇编语言源程序的结构汇编语言语句格式伪指令功能调用汇编语言程序设计4.1 概述概述一、一、机器语言机器语言(Machine Language)(Machine Language)二进制数形式的指令和数二进制数形式的指令和数据。据。 B0 64 B0 64 这就是机器语言。既不直观这就是机器语言。既不直观
2、, ,又不易理解和记忆又不易理解和记忆. . 目标程序目标程序(Object Program)(Object Program)用机器语言编写的程序用机器语言编写的程序 MOV AL,64H ;这就是;这就是助记符助记符。 助记符助记符用便于记忆的英语单词表示的指令操作码。它用便于记忆的英语单词表示的指令操作码。它反映了指令的功能和主要特征反映了指令的功能和主要特征,便于人们理解和记忆。便于人们理解和记忆。二、汇编语言二、汇编语言(Assembly Language)(Assembly Language)指令助记符指令助记符, ,符号地址,符号地址,标号,伪指令等语言元素的集合以及这些元素使用的
3、规则。标号,伪指令等语言元素的集合以及这些元素使用的规则。采用标号或符号来代替地址采用标号或符号来代替地址汇编语言源程序汇编语言源程序(Source Program)用汇编语言编写的程序。用汇编语言编写的程序。 操作数可能放在存储器中操作数可能放在存储器中,这就涉及操作数的地址。程序这就涉及操作数的地址。程序中遇到转移指令或调用指令中遇到转移指令或调用指令,也需要知道转移地址也需要知道转移地址,若采用若采用具体地址就很不方便具体地址就很不方便,一旦有错,改动也很麻烦。一旦有错,改动也很麻烦。10D1:0100 09750B OR DI+0B,SI10D1:0103 807C0A2C CMP B
4、YTE PTR SI+0A,2C10D1:0107 7505 JNZ 010E10D1:0109 FF36A22C PUSH 2CA210D1:010D 41 INC CX10D1:010E 93 XCHG BX,AX10D1:010F 33D2 XOR DX,DX10D1:0111 EBA7 JMP 00BA10D1:0113 33D2 XOR DX,DX10D1:0115 33C0 XOR AX,AX10D1:0117 FF36952C PUSH 2C9510D1:011B C3 RET10D1:011C 33D2 XOR DX,DX10D1:011E 0BC9 OR CX,CX汇编程序源
5、程序的编译程序源程序的编译程序汇编程序汇编程序汇编语言汇编语言源程序源程序机器语言机器语言目标程序目标程序 汇编源程序需翻译成机器语言汇编源程序需翻译成机器语言, ,变成可执变成可执行文件行文件, ,机器才能执行机器才能执行, ,这个翻译过程叫汇编。这个翻译过程叫汇编。高级语言中称该过程为高级语言中称该过程为“解释解释”或或“编编译译”。执行翻译的程序称为。执行翻译的程序称为“汇编程序汇编程序”。汇编语言程序设计与执行过程输入汇编语言源程序源文件 .ASM汇编(编译)目标文件 .OBJ链接可执行文件 .EXE调试最终程序MASM、DEBUG三、高级语言三、高级语言(High level Lan
6、guage)适合于描述各种算法,不依赖于计算机结构和指令系统。可移植性好,编成方法适合人们的习惯、通用性好。编译和解释程序复杂,占内存大,产生目标代码长。执行速度慢。处理中断和接口困难。高级语言源程序目标 程序编译编译软件程序或解释软件程序4.1.1 汇编语言源程序的结构 汇编语言源程序通常由一个或几个程序模块组成,每个模块一般一般由三个逻辑段组成: 数据段数据段存放数据、变量存放数据、变量 堆栈段堆栈段堆栈区域堆栈区域 代码段代码段存放程序指令存放程序指令堆栈段数据段代码段 stack SEGMENT PARA stack DB 100 DUP(stack) stack ENDS data
7、SEGMENT data ENDS code SEGMENT ASSUME CS:code, DS:data, ES:data start: MOV AX, data MOV DS, AX MOV ES, AX MOV AL, 4CH INT 21H code ENDS END start 一个基本的汇编语言程序框架如下:4.2 4.2 汇编语言源程序的格式与基本语法汇编语言源程序的格式与基本语法汇编语言的语句有三种:汇编语言的语句有三种:指令性语句指令性语句由由80868086指令助记符构成的语句,指令助记符构成的语句,由由CPU执行,每一条指令性语句都有一条执行,每一条指令性语句都有一条机
8、器机器码指令码指令与其对应。与其对应。指示性语句指示性语句由伪指令构成的语句,由由伪指令构成的语句,由汇编程汇编程序序执行。它指出汇编程序应如何对源程序进行执行。它指出汇编程序应如何对源程序进行汇编,如何定义变量、分配存储单元以及指示汇编,如何定义变量、分配存储单元以及指示程序开始和结束等。程序开始和结束等。指示性语句无机器码指令指示性语句无机器码指令与其相对应。与其相对应。 宏指令语句宏指令语句简化汇编语言,可以用一条宏指简化汇编语言,可以用一条宏指令指令代替定义过的一段程序,汇编时将该段令指令代替定义过的一段程序,汇编时将该段程序插入对应程序中。程序插入对应程序中。一、语句的种类一、语句的
9、种类指令性语句指令性语句的格式为: 标号标号: : 指令助记符指令助记符 目的操作数,源操作数目的操作数,源操作数 ; ;注释注释指示性语句指示性语句的格式为: 名字名字 伪指令伪指令 参数参数1,1,参数参数2,2,参数参数n n ; ;注释注释宏指令语句宏指令语句的格式为: 标号标号: 宏指令宏指令 参数参数1,参数参数2,参数参数n ;注释注释 注:各部分之间注:各部分之间至少至少要用一个空格作为分隔符。要用一个空格作为分隔符。二、语句的构成元素:二、语句的构成元素:标号标号标号标号指令的符号地址,用来代表指令在存储器中的指令的符号地址,用来代表指令在存储器中的指令的符号地址,用来代表指
10、令在存储器中的指令的符号地址,用来代表指令在存储器中的地址。地址。地址。地址。只能出现在指令性语句中,标号后应加上冒号。只能出现在指令性语句中,标号后应加上冒号。只能出现在指令性语句中,标号后应加上冒号。只能出现在指令性语句中,标号后应加上冒号。名字名字名字名字段、过程、变量的名字,用来代表它们在存储段、过程、变量的名字,用来代表它们在存储段、过程、变量的名字,用来代表它们在存储段、过程、变量的名字,用来代表它们在存储器中的地址。器中的地址。器中的地址。器中的地址。只能出现在指示性语句中,名字后不加冒只能出现在指示性语句中,名字后不加冒只能出现在指示性语句中,名字后不加冒只能出现在指示性语句中
11、,名字后不加冒号号号号。指令助记符指令助记符指令助记符指令助记符80868086助记符、伪指令助记符、伪指令助记符、伪指令助记符、伪指令操作数操作数操作数操作数即指令的操作对象即指令的操作对象即指令的操作对象即指令的操作对象 对指令性语句对指令性语句对指令性语句对指令性语句00,1 1,2 2个个个个 对指示性语句对指示性语句对指示性语句对指示性语句根据需要而定根据需要而定根据需要而定根据需要而定 操作数之间以逗号分隔操作数之间以逗号分隔操作数之间以逗号分隔操作数之间以逗号分隔 操作数可以是:操作数可以是:操作数可以是:操作数可以是:寄存器、存储单元、常数或表达式寄存器、存储单元、常数或表达式
12、寄存器、存储单元、常数或表达式寄存器、存储单元、常数或表达式 例如:例如:例如:例如:AXAX,DI+BX+10DI+BX+10,200200,16*8+TABLE16*8+TABLE,等等,等等,等等,等等注释注释以分号开头,可放在指令后,也可单独一行。 注意注解的写法。要写指令(段)在程序中的作用,而不要写指令的操作。 例如:以下为同一条指令写的注释 1)MOV CX,100 ;传送100到CX 2)MOV CX,100 ;循环计数器置初值 显然,第二种写法要比第一种写法要好。 datadata SEGMENT SEGMENTHello DB Hello, world!,0DH,0AH,$
13、data data ENDSENDSprogprog SEGMENT SEGMENT ASSUME CS:prog,DS:datastart: MOV AX,data MOV DS,AX LEA DX,hello;取字符串首地址 MOV AH,9 INT 21H;显示字符串 MOV AH,4CH INT 21H;退回DOSprogprog ENDS ENDS END END startstart名字标号 三、数据项与表达式三、数据项与表达式数据项包括数据项包括常量常量、变量变量、标号标号及及表达式表达式。常数常数二进制数二进制数, ,以以B B结尾。如结尾。如01001101B01001101
14、B。十进制数十进制数, ,如如8585。十六进制数十六进制数, ,以以H H结尾。第结尾。第1 1个数字为个数字为A-FA-F时,前面应加时,前面应加0 0,如,如0F160H0F160H。字字符符串串:用用引引号号括括起起来来的的1 1个个或或多多个个字字符符。如如ERROR!, ERROR!, a,a,汇汇编编时时被被翻翻译译成成对对应应的的ASCIIASCII码码45H,52H,52H,4FH,52H,21H45H,52H,52H,4FH,52H,21H和和61H61H。数值符号名:数值符号名:用伪指令定义的用伪指令定义的(EQU)(EQU)符号名符号名. .常常量量表表达达式式:用用各
15、各种种运运算算符符与与各各种种数数值值常常数数组组成成的的可可求求值值的的表达式。由汇编程序计算而得。表达式。由汇编程序计算而得。有三个属性: 段地址段地址:即标号所在段的段地址; 偏移量偏移量:标号所代表存储单元的段内偏移地址; 类类 型型:NEAR或FAR: NEAR表示标号所在语句与转移指令/ 调用指令在同一码段内,跳转时 只需改变IP即可。 FAR标号所在语句与转移指令/调用 指令不在同一代码段内。 若没有对类型进行说明,默认为NEAR。标号通常作为转移指令转移指令或CALLCALL指令指令的转移地址。2.标号指令所在内存单元的符号地址 变量即内存中的存储单元或数据区。 变量名是存储单
16、元(数据区)的符号地 址或名字。变量也有三个属性:段地址变量所在段的段地址偏移量变量单元地址与段首地址之间的位移量。类 型有BYTE、WORD和DWORD三种。变量在程序中作为存储器操作数存储器操作数被引用。标号和变量名的使用规则组成:A-Z(不分大小写), 0-9, ? . _ $不能以数字开头,句号(.)只能作为首字符长度小于31个字符不能与保留字(指令助记符、伪指令、预定义符号等)重名不能重复定义例如: 正确的:LP1, AGAIN, NEXT, _GO, OK_1 错误的:4M, LOOP, AAA, #HELP, +ONE表达式是常数、寄存器、标号、变量与运算符的组合。有数字表达式和
17、地址表达式两种。汇编时按优先规则对表达式进行计算,计算出具体的数值或地址。运行时不能改变。表达式中的运算符有5类:算术运算符、逻辑运算符、关系运算符、分析运算符和合成运算符。用于数字表达式,例: MOV AX,4*1024汇编后的形式为: MOV AX,4096 用于地址表达式,例: LEA SI,TAB+3若TAB的偏移地址为1000H,则汇编后的形式为: LEA SI,1003H 1)算术运算符 +、-、*、/,MOD,SHL,SHR逻辑运算符只能用于数字表达式中。 例:MOV CL,36H AND 0FH 经汇编后:MOV CL,06H注意,不要把逻辑运算符与逻辑运算指令混淆: 例:AN
18、D AX, 3FC0H AND 0FF00H 汇编后源操作数被翻译为:3F00H,所以上述指令与AND AX, 3F00H等价。2)逻辑运算符 AND、OR、XOR、NOT关系运算的结果是一个逻辑值:真真或假假 关系为真,结果为全1 关系为假,结果为全03)关系运算符EQ、NE、LT、GT、LE、GE例:MOV BX,PORT GT 300H;若PORT的值大于300H,则汇编后为:MOV BX,0FFFFH否则汇编后为: MOV BX,0 例:MOV BX,(PORT GT 300H) AND 20H) OR (PORT LE 300H) AND 30H)MOV BX,(PORT GT 30
19、0H) AND 20H) OR (PORT LE 300H) AND 30H) 若PORT的值大于300H,则汇编后为: MOV BX,20H 否则汇编后为: MOV BX,30HSEG:取变量/标号的段地址OFFSET:取变量/标号的偏移地址例:VAR DB 12H MOV BX,OFFSET VAR ;取变量VAR的偏移地址 MOV AX,SEG VAR ;取变量VAR的段地址注意,以下指令的异同: MOV BX, OFFSET VAR LEA BX, VAROFFSET只能取静态的偏移地址;LEA指令即可取静态的偏移地址,也可取动态的偏移地址。 取地址运算符SEG、OFFSET4)分析运
20、算符: 分析对MEM(变量或标号)的三个重要的属性。TYPE 取变量的类型(取变量的类型(1,2,4)LENGTH 取所定义变量的长度取所定义变量的长度 (即变量中元素的个数)(即变量中元素的个数)SIZE 取所定义存储区的字节数取所定义存储区的字节数 (=TYPE*LENGTH)例:例:VAR DW 20 DUP(?),2 DAT1 DB 5,1 则 TYPE VAR = 2 LENGTH VAR = 20 SIZE VAR = 40LENGTH、SIZE 仅用于带DUP的外层有效 取值运算符TYPE、LENGTH、SIZE格式 运算符 操作数SEGOFFSETTYPE变量名或标号变量名或标
21、号标号或变量名返回其所在段的段基址返回其所在段的偏移地址返回其属性值NEAR、FARDB、DW、DD、DQ、DT变量名变量名LENGTHSIZE1、 2、 4、 8、 10-1、 -2元素个数字节数SIZE=TYPE*LENGTH用于带DUP的外层有效6)合成运算符PTR、THIS用来指定地址操作数的类型。格式: PTR 类型BYTE, WORD, DWORD, NEAR, FARBYTE、WORD、DWORD 用于描述数据存储单元(变量)地址NEAR、FAR 用于描述转移、调用的目的地址变量:指令中临时指定的变量的新属性可利用PTR指定地址相同而类型不同的新变量例:MOVBYTE PTRDI
22、,0 ;字节类型 MOVWORD PTRDI,0 ;字类型 MOVDI,0B5H ;类型不定例: STR1 DW ? ;STR1定义为字类型 STR2 EQU BYTE PTR STAR1 MOVAX,STR1 ;合法 MOVAL,STR1 ;非法 MOV AL,BYTE PTR STR1 ;合法 MOV AL,STR2标号:可用PTR建立地址相同而类型不同的新符号。 可临时指定其标号的新属性。C1 SEGMENT ASSUME C1:CS JMP NEAR PTR NEXT;超前引用FNEXT EQU FAR PTR NEXT FFNEXT EQU THIS FARNEXT:MOV BX,1
23、00C2 SEGMENT C2:CS JMP FNEXT符号符号equ this类型类型另一符号另一符号;放于被指定类型前放于被指定类型前6.汇编运算符(THIS)格式:THIS 类型 可以像PTR一样建立一个指定类型的地址操作数,该操作数的段地址和偏移地址与下一个存储单元地址相同。例:BUFB EQU THIS BYTEBUFW DW 1234H,5678H.MOV AX,BUFW ;AX=1234HMOV BL,BUFB ;BL=34HBUFB的偏移地址和BUFW完全相同,但它是字节类型;而BUFW则是字类型。P237页 运算符的优先级4.3 伪操作命令与宏指令数据定义伪指令符号定义伪指令
24、模块定义伪指令(段)过程定义伪指令宏指令模块连接列表伪指令 由汇编程序执行的指令,它本身不被汇编成机器指令。这里仅介绍MASM常用的伪指令。4.3.1 数据定义与存储器分配伪指令(define) 用于定义变量,即内存单元或数据区。数据定义伪指令的格式为: 变量名变量名 数据定义伪指令数据定义伪指令 操作数,操作数,操作数,操作数, DB、DW、DD、DQ、DT 作用:定义变量类型属性,并可以进行初始化常数或表达式字符串(hello表示其ASC值的)?(该单元不初始化,预留出存储空间)带DUP表达式 n dup(操作数)带$(表示地址计数器当前值)常数或表达式:DATA_B DB 10,5,10
25、HDATA_W DW 100H,-4DATA_D DD 0FFFBH05H10H00H01HFCHFFHFBHFFH00H00H0AHDATA_BDATA_BDATA_WDATA_WDATA_DDATA_D10105 510H10H100H100H- - - -4 40FFFBH0FFFBHSTRHELLO48H45H4CH4CH4FH注意下面两个定义的不同之处:DBAB;41H在低字节 ;42H在高字节DW AB;42H在低字节, ;41H在高字节操作数可以是字符串,例如STR DBHELLO操作数?用来保留存储空间,但不存入数据.例3:ABC DB 0,1,2,3,4,OK,$ RSV D
26、W ?,?,?,?,?,?,?,?复制操作符DUP:重复的数据可以使用复制操作符DUP,如上面RSV亦可写成: RSV DW 8 DUP(?)若操作数中若使用$,则表示的是地址计数器的当前值。例: TABLE DB 10 DUP(?) BUFFER DW TABLE,$+3设TABLE的偏移地址为0080H,则汇编后如下图所示:$ $表示当前存储单元的偏移地址。表示当前存储单元的偏移地址。BUFFER0080H80HTABLE008AH008BH008CH008DH.8FH00H00H0089H10 BytesDAT8DAT7DAT6DAT5DAT4DAT3DAT2DAT115H14H13H1
27、2H11H10H0FH0EH0DH0CH0BH0AH9H8H7H6H5H4H3H2H1H0000HDATA SEGMENT DAT1 DB 40H DAT10 EQU WORD PTR DAT1 DAT9 EQU THIS WORD DAT2 DW 00H,23H DAT3 DB 2 DUP(20H) DAT4 DB AB DAT5 DW AB DAT6 DW ?,$+3 DAT7 DB 25H*4 A1 EQU 10H DAT8 DB 2 DUP(2 DUP(A1)DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA MOV AX,DATA MOV DS,
28、AX MOV BX,SEG DAT2 MOV CX,OFFSET DAT2XX: MOV DX,TYPE DAT2 MOV AX,TYPE XX MOV AL,LENGTH DAT3 MOV AH,LENGTH DAT8 MOV BL,SIZE DAT8 mov ah,4ch int 21hCODE ENDS END?H?H10H00H94H10H10H10H10H09H10H41H42H42H41H20H20H00H23H00H00H40HDAT9DAT10-D1254:0000 40 00 00 23 00 20 20 41-42 42 41 00 00 10 00 94 .#. ABBA
29、.1254:0010 10 10 10 10 00 00 00 00-00 00 00 00 00 00 00 00 .1254:0020 B8 54 12 8E D8 BB 54 12-B9 01 00 BA 02 00 B8 FF 8T.X;T.9.:.8.1254:0030 FF B0 02 B4 00 B3 00 B4-4C CD 21 00 00 00 00 00 .0.4.3.4LM!.1254:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1254:0050 00 00 00 00 00 00 00 00-00 00
30、00 00 00 00 00 00 .1254:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1254:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .-AX=0000 BX=0000 CX=0082 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1244 ES=1244 SS=1254 CS=1254 IP=0020 NV UP DI PL NZ NA PO NC1254:0020 B85412 MOV AX,1254-TAX=125
31、4 BX=0000 CX=0082 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1244 ES=1244 SS=1254 CS=1254 IP=0023 NV UP DI PL NZ NA PO NC1254:0023 8ED8 MOV DS,AX-TAX=1254 BX=0000 CX=0082 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=0025 NV UP DI PL NZ NA PO NC1254:0025 BB5412 MOV BX,1254
32、-TAX=1254 BX=1254 CX=0082 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=0028 NV UP DI PL NZ NA PO NC1254:0028 B90100 MOV CX,0001-TAX=1254 BX=1254 CX=0001 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=002B NV UP DI PL NZ NA PO NC1254:002B BA0200
33、 MOV DX,0002-AX=1254 BX=1254 CX=0001 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=002E NV UP DI PL NZ NA PO NC1254:002E B8FFFF MOV AX,FFFF-TAX=FFFF BX=1254 CX=0001 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=0031 NV UP DI PL NZ NA PO NC1254:
34、0031 B002 MOV AL,02-TAX=FF02 BX=1254 CX=0001 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=0033 NV UP DI PL NZ NA PO NC1254:0033 B402 MOV AH,02-TAX=0202 BX=1254 CX=0001 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=0035 NV UP DI PL NZ NA PO NC1
35、254:0035 B302 MOV BL,02-TAX=0202 BX=1202 CX=0001 DX=0002 SP=0000 BP=0000 SI=0000 DI=0000DS=1254 ES=1244 SS=1254 CS=1254 IP=0037 NV UP DI PL NZ NA PO NC1254:0037 B44C MOV AH,4C-4.3.2 符号定义伪指令用EQU定义的符号未清除前,不能重新定义。清除EQU定义可用PURGE伪指令。用”=”定义的符号可在任何时候进行重定义。二者二者均不占用存储空间,仅是给符号赋值 格式:格式: 符号名符号名 EQU或或= 表达式表达式把一个
36、表达式用一个符号表示,以后凡出现该表达式的地方都可用这个符号表示。类似于C语言中的#define。符号定义伪指令有两种:EQU,=可以为数值和地址及其表达式,变量,标号、指令助记符例:FIVE EQU 5 COUNT EQU CX TEN EQU 10 DIST = BYTE PTRSI+BP GOTO = JMP MOV AX, TEN MOV CX, COUNT ADD DIST, FIVE DIST = WORD PTRSI+BP+1 ADD DIST, AX GOTO LABEL 定义定义引用引用4.3.3 程序模块定义伪指令当功能复杂、大型的程序设计任务,先分解成多个相对独立的小任务
37、,单独编写 、调试、汇编。格式格式: NAME module_name1、NAME可省2、NAME省后文件模块名? (1)若有TITLE test ,默认test前6字符 (2)都无,为源文件名(x.asm)为模块名TITLE test END 表达式表达式最多6个字符,以字母开头可指定每页的打印标题,60多字符(列表文件上)1、可不加表达式,默认第一条成机器码指令的地址2、每个模块仅有一个END 主模块:END 表达式,为第一条代码的标号。 子模块:不加表达式汇编结束伪指令,END后不形成机器码一、模块定义伪指令二、段定义伪指令汇编语言源程序是按段来组织程序和数据的。 汇编语言程序中的段称为
38、逻辑段。 汇编连接后被映射到物理段中。三类段:代码(程序)、数据、堆栈段定义伪指令:SEGMENTSEGMENT、ENDSENDS、ASSUMEASSUME、ORGORG定义一个段的基本格式: 段名段名 SEGMENT 定位类型定位类型定位类型定位类型组合方式组合方式组合方式组合方式类别类别类别类别 段名段名 ENDS这两个伪指令总是成对出现,二者前面的段名应一致。SEGMENT说明了一个段的开始,ENDS说明了一个段的结束。对数据段和堆栈段,段中的语句一般是变量定义。对代码段则是指令语句。如: data SEGMENT data ENDS (一一)SEGMENT和ENDS伪指令伪指令SEGM
39、ENTSEGMENT语句后可以带有可选参数语句后可以带有可选参数语句后可以带有可选参数语句后可以带有可选参数,用以,用以,用以,用以规定规定规定规定逻辑段的其他一些逻辑段的其他一些逻辑段的其他一些逻辑段的其他一些属性。属性。属性。属性。1) 定位类型定位类型说明说明如何确定逻辑段的边界。有四种:如何确定逻辑段的边界。有四种:PARAPARA(Paragraph):(Paragraph): 逻辑段从一个节 (16个字节) 的边界开始。即段的起始地址应能被16整除, 或这说段起始物理地址应为0H。默认类型BYTE :BYTE : 逻辑段从字节边界开始,即段可以从任何地址开始。WORD :WORD
40、: 逻辑段从字边界开始。即段的起始地址必须是偶数。PAGE :PAGE : 逻辑段从页边界开始。256字节称为一页,故段的起始物理地址应为00H。 2) 组合类型组合类型说明不同模块中同名段的组合方式。PUBLIC : 所有此类型的同名段同名段组合成一个逻辑段,公用一个段地址,运行时装入同一个物理段中。COMMON : 所有此类型的同名段具有相同的起始地址(覆盖),共享相同的存储区域。AT : 按绝对地址定位,段地址就是表达式的值。STACK : 专用于说明堆栈段,组合方式同PUBLIC3) 类别类别用单引号括起来的字符串。所有同类别的段被安排在连续的存储区域中。如:在模块1中有段定义: se
41、g1 SEGMENT PARA STACK stack seg1 ENDS 在模块2中有段定义: seg2 SEGMENT PARA STACK stack seg2 ENDS则连接时这两个段被安排在一起。(二二)、ASSUME伪指令伪指令功能:在代码段中,说明段和段寄存器的关系,并未将段寄存器赋值。格式:ASSUME ASSUME 段寄存器段寄存器: :段名段名, ,段寄存器段寄存器: :段名段名例:例: ASSUME CS:code, DS:data, ES:dataASSUME CS:code, DS:data, ES:data:程序段比为CS,堆栈段必须为SS 该语句一般放于代码段的最
42、前面。 仅是说明性语句,除CS外(由系统赋值),各段寄存器均需在程序中赋值 取消语句 ASSUME NOTHINGASSUME NOTHING 段寄存器的填入:段寄存器的填入:1、代码段段寄存器代码段段寄存器CS及指令指针及指令指针IP的填入的填入 当汇编程序扫描到程序结束伪指令END符号地址时, 系统自动将当前代码段基址CS 同时将END后面的符号地址的偏移地址IP, (若无符号地址,将第一条可执行性语句的偏移地址IP)2、数据段段寄存器数据段段寄存器DS及扩展数据段段寄存器及扩展数据段段寄存器ES的填入的填入 由指令填入 MOV AX,段名 MOV DS,AX MOV AX,段名 MOV
43、ES,AX3、堆栈段段寄存器SS及堆栈指针SP的填入 系统自动填入 当定义段的组合类型为STACK时。即STACK SEGMENT STACK ;将相同名连接在一起形成一个大的堆栈段;将相同名连接在一起形成一个大的堆栈段 DW 200 DUP(?) STACK ENDS系统自动将此段段基址SS 段长度SP 用指令填入 当定义段的组合类型缺省(非STACK) 代码段中用MOV指令来完成 S_SEG SEGMENT STA DB 200 DUP(?)S_SEG ENDSC_SEG SEGMENT ASSUME CS:C_SEG,SS:S_SEGSTART:MOV AX,S_SEG MOV SS,A
44、X MOV SP,SIZE STA ;或mov sp,length staCODE ENDSS_SEG SEGMENT STA DB 200 DUP(?) top equ size sta ;或 top equ length staS_SEG ENDSC_SEG SEGMENT ASSUME CS:C_SEG,SS:S_SEGSTART:MOV AX,S_SEG MOV SS,AX MOV SP,TOPCODE ENDSORG规定了段内的指令或数据存放的开始地址(偏移地址的初值),其格式为: ORG 表达式的值即为开始地址,从此地址起连续存放程序或数据。例: ABC SEGMENT ORG 1
45、00H begin: ABC ENDS (三三)、ORG伪指令伪指令指令从100H开始存放4.3.4 4.3.4 过程定义伪指令过程定义伪指令PROCPROC、ENDPENDP过程就是子程序。一个过程可以被其它程序所调用(用CALL指令),过程的最后一条指令一般是返回指令(RET) 过程定义伪指令的格式为 PROCPROC 类型类型 RET RET ENDPENDP 注意:注意:PROCPROC和和ENDPENDP必须成对出现。必须成对出现。 过程的类型有两种: NEAR(默认类型)表示段内调用 FAR表示段间调用调用一个过程的格式为:CALL 4.3.5 4.3.5 宏定义伪指令宏定义伪指令
46、如果需要多次使用同一个程序段,可以将这个程序段定义为一个”宏指令”,然后在需要时,可简单地用宏指令名宏指令名来代替这个程序段。指令的格式为:指令的格式为: MACRO 形参表形参表 ENDM例:两个数之和的宏定义和宏调用。 宏定义为:DADD DADD MACROMACRO X X,Y Y,Z Z MOV AX MOV AX,X X ADD AX ADD AX,Y Y MOV Z MOV Z,AXAX ENDMENDMX、Y、Z是形式参数。调用宏DADD时可写为: DADD DATA1,DATA2,SUMDATA1,DATA2,SUM是实际参数,由它们替换定义中的X、Y、Z。宏调用与过程(子程
47、序)调用都是一次定义,多次调用。它们之间的差别是: 执行形式执行形式:宏命令伪指令由宏汇编程序在汇编过理中进行处理,而CALL、RET则是由CPU执行的指令。 汇编结果汇编结果:宏命令伪指令汇编后被展开。 执行速度执行速度:宏命令执行速度较快(因无调用转移) 占用内存占用内存:宏指令简化了源程序,但不能简化目标程序,并不节省内存单元。使用过程可以节省代码占用的内存空间。宏展开:汇编程序会把宏调用按宏定义展开。宏展开:汇编程序会把宏调用按宏定义展开。例如:宏定义为:例如:宏定义为: Display MACRO string LEA DX,string MOV AH,9 INT 21H ENDM
48、程序中宏调用:程序中宏调用: DISPLAY ERROR_MESSAGE DISPLAY EXIT_MESSAGE 汇编后的结果:汇编后的结果:(带有带有+号的指令为宏展开后的结果号的指令为宏展开后的结果) + LEA DX,ERROR_MESSAGE + MOV AH,9 + INT 21H + LEA DX,EXIT_MESSAGE + MOV AH,9 + INT 21H 4.3.6 4.3.6 模块连接伪指令模块连接伪指令用于模块之间的共享信息。用于模块之间的共享信息。即即即即A A模块中的变量和标号被模块中的变量和标号被模块中的变量和标号被模块中的变量和标号被B B模块使用时必须加以
49、说明模块使用时必须加以说明模块使用时必须加以说明模块使用时必须加以说明一、一、PUBLIC;本模块说明;本模块说明格式:格式:PUBLIC 符号名符号名1 ,符号名,符号名2功能:公共引用,说明本模块定义,功能:公共引用,说明本模块定义,其它模块引用的共享信息。其它模块引用的共享信息。二、二、EXTRN;引用外模块的说明;引用外模块的说明(external)格式:格式:EXTRN 符号名:类型,符号名:类型符号名:类型,符号名:类型功能:其他模块定义的,本模块引用。功能:其他模块定义的,本模块引用。 NAME AEXTRN VAR2:WORD,LAB2:FARPUBLIC VAR1,LAB1,
50、VAR4DATA1 SEGMENT VAR1 DB 12H,34H VAR3 DW 10 DUP(?) VAR4 DW 10 DUP(?)DATA1 ENDS NAME BEXTRN VAR1:BYTE,VAR4:WORDPUBLIC VAR2DATA2 SEGMENT VAR2 DW 0 VAR5 DB 5 DUP(0)DATA2 ENDS NAME CEXTRN LAB1:FAR,VAR5:BYTEPUBLIC LAB2存储模式决定了一个程序的规模,也确定了子程序调用、指令转移和数据访问等的缺省属性当使用简化段定义的源程序格式时,必须有存储模式.MODEL语句,且位于所有简化段定义语句之前
51、。其格式为:.MODEL 存储模式.MODEL语句确定了程序采用的存储模式,MASM有7种可以选择4.3.7 存储模式(存储模式(Memory Model)2. 逻辑段的简化定义.STACK 大小;堆栈段定义伪指令.STACK创建一个堆栈段,段名是:STACK。可选的“大小”参数指定堆栈段所占存储区的字节数,默认是1KB(1024400H字节).DATA;数据段定义伪指令.DATA创建一个数据段,段名是:_DATA。数据段名可用DATA预定义标识符表示.CODE 段名;代码段定义伪指令.CODE创建一个代码段,可选的“段名”参数指定该代码段的段名。如果没有给出段名,则采用默认段名 一个段的开始
52、自动结束前面的一个段简化段定义伪指令之前,需有存储模式语句3. 程序开始为了指明程序开始执行的位置,需要使用一个标号(例题中采用了start标识符)连接程序会根据程序起始点正确地设置CS和IP值,根据程序大小和堆栈段大小设置SS和SP值连接程序没有设置DS和ES值。程序如果使用数据段或附加段,必须明确给DS或ES赋值大多数程序需要数据段,程序的执行开始应是:start: mov ax,data;data表示数据段的段地址mov ds,ax ;设置DS4. 程序终止应用程序执行结束,应该将控制权交还操作系统汇编语言程序设计中,有多种返回DOS的方法,但一般利用DOS功能调用的4CH子功能实现,它
53、需要的入口参数是AL返回数码(通常用0表示程序没有错误)于是,应用程序的终止代码就是:mov ax,4c00hint 21h5. 汇编结束汇编结束表示汇编程序到此结束将源程序翻译成目标模块代码的过程源程序的最后必须有一条END伪指令END 标号可选的“标号”参数指定程序开始执行点,连接程序据此设置CS和IP值(例题中采用了start标识符) 不要糊涂程序终止和汇编结束是两码事第一个源程序文件;.model small.stack.datastringdb Hello, Assembly !,0dh,0ah,$.codestart:mov ax,datamov ds,axmov dx,offse
54、t stringmov ah,9int 21hmov ax,4c00hint 21hend start简化段定义的源程序格式.model small;小型模式存储模式.stack; 1KB空间堆栈段.data;数据段;数据定义.code;代码段start:mov ax,data;起始点mov ds,ax;设置DS;程序代码mov ax,4c00hint 21h;结束点,返回DOS;子程序代码end start;汇编结束完整段定义格式完整段定义利用SEGMENT和ENDS一对伪指令定义逻辑段同时需要配合ASSUME伪指令指明逻辑段是代码段、堆栈段、数据段还是附加段完整段定义的优势是可以指明逻辑段
55、的定位、组合、类别等属性;而简化段定义只能采用系统默认的属性完整段定义和简化段定义的实质是一致的 2.汇编汇编 汇汇编编就就是是用用宏宏汇汇编编程程序序把把汇汇编编语语言言源源程程序序翻翻译译(汇汇编编)成成机机器语言的目标程序。宏汇编程序主要有以下功能:器语言的目标程序。宏汇编程序主要有以下功能:检查源程序中语法错误,给出错误信息;检查源程序中语法错误,给出错误信息;展开宏指令;展开宏指令;生生目目标标程程序序(.OBJ),列列表表文文件件(.LST)和和交交叉叉引引用用文文件件(.CRF)。)。4.3.8 汇编语言上机调试汇编语言上机调试 调用编辑程序等,用键盘敲入源程序,退出编辑调用编辑
56、程序等,用键盘敲入源程序,退出编辑系统时,保存编辑完成的文件,且扩展名为系统时,保存编辑完成的文件,且扩展名为.ASM。接着屏幕上显示:接着屏幕上显示:宏汇编程序询问汇编产生的目标程序文件(目标程序文件是一个宏汇编程序询问汇编产生的目标程序文件(目标程序文件是一个纯二进制代码文件,不能直接在屏幕上显示观察)的文件名是否纯二进制代码文件,不能直接在屏幕上显示观察)的文件名是否为方括号中的默认值(即目标程序与源程序同名)。若是,直接为方括号中的默认值(即目标程序与源程序同名)。若是,直接按一回车键,否则需自己输入另一文件名。在回答完这一询问后,按一回车键,否则需自己输入另一文件名。在回答完这一询问
57、后,宏汇编程序接着依次询问产生列表文件(列表文件宏汇编程序接着依次询问产生列表文件(列表文件.LST是一个很是一个很有用的文件,文件中包含了源程序中各语句及其对应的目标代码。有用的文件,文件中包含了源程序中各语句及其对应的目标代码。给出了源程序中各语句所属段内的偏移量,并且把源程序中所用给出了源程序中各语句所属段内的偏移量,并且把源程序中所用的标号、变量和符号,列出它们的名字、类型和值,便于查阅)的标号、变量和符号,列出它们的名字、类型和值,便于查阅)和交叉引用文件(交叉引用文件中给出了源程序中定义的符号如和交叉引用文件(交叉引用文件中给出了源程序中定义的符号如标号、变量等以及程序中引用这些符
58、号的情况,且是按字母顺序标号、变量等以及程序中引用这些符号的情况,且是按字母顺序排列的。若要查看这个符号表,必须使用排列的。若要查看这个符号表,必须使用CREF软件,它根据软件,它根据.CRF文件建立一个扩展名为文件建立一个扩展名为.REF的文件。然后再显示的文件。然后再显示.REF文件的内容文件的内容就可以看到这个符号表)的文件名,屏幕上显示:就可以看到这个符号表)的文件名,屏幕上显示:这这两两个个文文件件是是否否建建立立由由操操作作人人员员确确定定:若若要要建建立立其其中中一一个个或或两两个个,操操作作人人员员便便可可输输入入所所需需建建立立的的文文件件名名,否否则则直直接接送送入入回回车
59、车键键。待待完完成成上上述述人人机机对对话话后后,宏宏汇汇编编程程序序便便对对源源程程序序进进行行扫扫描描,检检查查源源程程序序中中各各语语句句是是否否有有语语法法错错误误,同同时时把把各各语语句句汇汇编编成成对对应应的的机机器器目目标标代代码码。在在汇汇编编过过程程中中,若若发发现现源源程程序序有有语语法法错错误误,便便随随时时给给出出出出错错信信息息。屏屏幕幕上上显示:显示:如如果果警警告告错错误误和和严严重重错错误误总总数数都都等等于于零零,那那么么这这次次源源程程序序的的汇汇编编获获得得通通过过,可可以以进进行行连连接接。否否则则,返返回回编编辑辑程程序序,修修改改源源程程序序,然然后
60、后再再次次进行汇编,直到源程序汇编正确无误。进行汇编,直到源程序汇编正确无误。 如如果果汇汇编编时时,无无须须产产生生列列表表文文件件和和交交叉叉引引用用文文件件,则则在在启启动动宏宏汇汇编编程序时可用分号结尾,比如:程序时可用分号结尾,比如:C:MASM TEST; 如如果果需需要要后后面面的的列列表表文文件件和和交交叉叉引引用用文文件件,且且它它们们的的文文件件名名与与源源文文件名相同,这时启动宏汇编程序时,可用逗号指明,比如:件名相同,这时启动宏汇编程序时,可用逗号指明,比如:C:MASM TEST,;,; 源程序经过汇编后产生的目标程序,必须经过连接程序连接后源程序经过汇编后产生的目标
61、程序,必须经过连接程序连接后才能运行。才能运行。连接程序把一个或多个独立的目标程序模块连接装配成一个可重定连接程序把一个或多个独立的目标程序模块连接装配成一个可重定位的可执行文件(扩展名为位的可执行文件(扩展名为.EXE)。连接程序)。连接程序LINK除产生一个可执除产生一个可执行文件外,还可产生一个内存映象文件(扩展名为行文件外,还可产生一个内存映象文件(扩展名为.MAP)。)。LINK连连接的一定是扩展名为接的一定是扩展名为.OBJ的目标程序。的目标程序。在操作系统状态下,直接启动连接程序在操作系统状态下,直接启动连接程序LINK.EXE。例如例如:C:LINK TEST 接着屏幕上显示:
62、接着屏幕上显示: 连连接接程程序序询询问问连连接接时时产产生生的的可可执执行行文文件件名名是是否否用用方方括括号号中中的的默默认认值值(即即可可执执行行文文件件与与目目标标程程序序文文件件同同名名)。若若是是,可可直直接接按按一一回回车车键键,否否则则需需要要重重新新输输入入一一文文件件名名。接接着着依依次次询询问问,屏屏幕幕上上显显示:示:其其中中MAP文文件件(MAP文文件件列列出出各各段段的的起起点点,终终点点及及长长度度。)是是否否建建立立,由由操操作作人人员员确确定定。若若要要,则则输输入入一一文文件件名名,否否则则直直接接送送一一回回车车键键。后后一一个个是是询询问问在在连连接接时
63、时是是否否要要用用库库文文件件。对对于于来来自自宏宏汇汇编编语言程序的目标程序文件,通常是直接送一回车键。语言程序的目标程序文件,通常是直接送一回车键。与与启启动动宏宏汇汇编编程程序序一一样样,可可以以在在启启动动连连接接程程序序时时,用用分分号号结结束束后后续续询问。如询问。如:C:LINK TEST; 若要产生若要产生MAP文件,且使用目标程序文件名,可用一逗号表示。文件,且使用目标程序文件名,可用一逗号表示。C:LINK TEST,;,; 若若需需要要连连接接多多模模块块的的目目标标程程序序时时,可可用用“+”把把它它们们连连接接起来。例如连接三个目标程序文件、,其操作如下:起来。例如连
64、接三个目标程序文件、,其操作如下:C:LINK P1+P2+P3; 这这样样产产生生的的一一个个可可执执行行文文件件是是约约定定取取用用第第一一个个目目标标程程序序文文件名,当然操作人员也可重新用另外的文件名。件名,当然操作人员也可重新用另外的文件名。在建立好可执行文件后,就可以直接从在建立好可执行文件后,就可以直接从DOS执行程序,如下所示:执行程序,如下所示:C: C: 程序运行结束后返回程序运行结束后返回DOS。如果用户程序已直接把结果在终端。如果用户程序已直接把结果在终端上显示出来,那么程序已经运行结束,结果也已经得到了。上显示出来,那么程序已经运行结束,结果也已经得到了。生成生成 .
65、COM文件文件 .COM文件也是一种可执行文件,由程序本身的二进制代码组成,它没有 .EXE文件所具有的包括有关文件信息的标题区(HEADER),因此它占有的存储空间比 .EXE文件要小。.COM文件不允许分段,它所占有的空间不允许超过64 KB,因而只能用来编制较小的程序。由于其小而简单,装入速度比 .EXE文件要快。 使用 .COM文件时,程序不分段,其入口点(开始运行的起始点)必须是100H(其前的256个字节为程序段前缀所在地),且不必设置堆栈段。在程序装入时,由系统自动把SP建立在该段之末。对于所有的过程则应定义为NEAR。用户在建立源文件以后,同样经过汇编、连接生成 .EXE文件,
66、然后可以通过DOS操作系统下的EXE2BIN程序来建立 .COM文件,操作方法如下: C:EXE2BIN FILENAME FILENAME.COM 请读者注意,上行中的第一个FILENAME给出了已形成的 .EXE文件的文件名,但不必给出文件扩展名。第二个FILENAME即为所要求的 .COM文件的文件名,它必须带有文件扩展名 .COM,这样就形成了所要的 .COM文件。在DOS系统下,可直接在机器上键入文件名以执行程序。如果第二个FILENAME后不跟扩展名,则将形成 .BIN文件,在DOS系统下运行该程序时,必须先用RENAME命令把它改名为 .COM文件才能直接运行。 此外,.COM文
67、件还可以直接在调试程序DEBUG中用A或E命令建立,对于一些短小的程序,这也是一种相当方便的方法。程序的调用程序的调用在在DOS的提示符下,可键入命令:的提示符下,可键入命令:C:DEBUG D:PATHFILENAME.EXEPARM1PARM2其其中中,文文件件名名是是被被调调试试文文件件的的名名字字。如如用用户户键键入入文文件件,则则DEBUG将指定的文件装入存储器中,用户可对其进行调试。将指定的文件装入存储器中,用户可对其进行调试。如如果果未未键键入入文文件件名名,则则用用户户可可以以用用当当前前存存储储器器的的内内容容工工作作,或或者者用用DEBUG命令命令N和和L把需要的文件装入存
68、储器后再进行调试。把需要的文件装入存储器后再进行调试。命命令令中中的的D指指定定指指定定驱驱动动器器PATH为为路路径径,PARM1和和PARM2则则为为运行被调试文件时所需要的命令参数。运行被调试文件时所需要的命令参数。4.3.9 DEBUG主要命令主要命令 DEBUG是为汇编语言设计的一种高度工具,它通过单步、设是为汇编语言设计的一种高度工具,它通过单步、设置断点等方式为汇编语言程序员提供了非常有效的调试手段。置断点等方式为汇编语言程序员提供了非常有效的调试手段。的主要命令的主要命令(1)显示存储单元的命令)显示存储单元的命令D(DUMP),格式为:,格式为:_Daddress或或_Dra
69、nge例如,例如,D命令的使用情况如下:命令的使用情况如下:(2)修改存储单元内容的命令有两种。)修改存储单元内容的命令有两种。输入命令输入命令E(ENTER),有两种格式如下:,有两种格式如下:第第一一种种格格式式可可以以用用给给定定的的内内容容表表来来替替代代指指定定范范围围的的存存储储单单元元内内容。命令格式为:容。命令格式为:-E address list例如,例如,-E DS:100 F3XYZ8D第二种格式则是采用逐个单元相继修改的方法。命令格式为:第二种格式则是采用逐个单元相继修改的方法。命令格式为:-E address(3)检查和修改寄存器内容的命令)检查和修改寄存器内容的命令
70、R(register)它有三种格式它有三种格式显示显示CPU内所有寄存器内容和标志位状态,其格式为:内所有寄存器内容和标志位状态,其格式为:-R显示和修改某个寄存器内容,其格式为:显示和修改某个寄存器内容,其格式为:-R register name显示和修改标志位状态,命令格式为:显示和修改标志位状态,命令格式为:-RF(4)运行命令)运行命令G,其格式为:,其格式为:-G=address1address2address3 其其中中,地地址址1指指定定了了运运行行的的起起始始地地址址,如如不不指指定定则则从从当当前前的的CS:IP开开始始运运行行。后后面面的的地地址址均均为为断断点点地地址址,
71、当当指指令令执执行行到到断断点点时时,就就停停止止执执行行并并显显示示当当前前所所有有寄寄存存器器及及标标志志位位的的内内容容,和和下下一一条条将将要执行的指令。要执行的指令。(5)跟踪命令)跟踪命令T(Trace),有两种格式,有两种格式:逐条指令跟踪逐条指令跟踪-T=address从指定地址起执行一条指令后停下来,显示所有寄存器内容及标从指定地址起执行一条指令后停下来,显示所有寄存器内容及标志位的值。如未指定地址则从当前的志位的值。如未指定地址则从当前的CS:IP开始执行。开始执行。多条指令跟踪多条指令跟踪-T=addressvalue从指定地址起执行从指定地址起执行n条指令后停下来,条指
72、令后停下来,n由由value指定指定。(6)汇编命令)汇编命令A(Assemble),其格式为:,其格式为:-Aaddress该该命命令令允允许许键键入入汇汇编编语语言言语语句句,并并能能把把它它们们汇汇编编成成机机器器代代码码,相相继继地地存存放放在在从从指指定定地地址址开开始始的的存存储储区区中中。必必须须注注意意:DEBUG把把键键入入的的数数字字均均看看成成十十六六进进制制数数,所所以以如如要要键键入入十十进进制制数数,则则其其后后应应加加以以说明,如说明,如120D。(7)反汇编命令)反汇编命令U(Unassemble)有两种格式。有两种格式。从指定地址开始,反汇编从指定地址开始,反
73、汇编32个字节,其格式为:个字节,其格式为:-Uaddress如果地址被省略,则从上一个如果地址被省略,则从上一个U命令的最后一条指令的下一个单元命令的最后一条指令的下一个单元开始显示开始显示32个字节。个字节。对指定范围内的存储单元进行反汇编,格式为:对指定范围内的存储单元进行反汇编,格式为:-Urange(8)命名命令)命名命令N(Name),其格式为:,其格式为:-N filespecs filespecs命命令令把把两两个个文文件件标标识识符符格格式式化化在在CS:5CH和和CS:6CH的的两两个个文文件件控控制制块块中中,以以便便在在其其后后用用L或或W命命令令把把文文件件装装入入存
74、存盘盘。filespecs的的格格式式可以是:d:pathfilename.ext(9)装入命令)装入命令(Load),有两种功能。,有两种功能。 把磁盘上指定扇区范围的内容装入到存储器指定地址开始的区把磁盘上指定扇区范围的内容装入到存储器指定地址开始的区域中。其格式为:域中。其格式为:-Laddressdrive sector sector装入指定文件,其格式为:装入指定文件,其格式为:-Laddress此命令装入已在此命令装入已在CS:5CH中格式化了文件控制块所指定的文件。如中格式化了文件控制块所指定的文件。如未指定地址,则装入未指定地址,则装入CS:0100开始的存储区中。开始的存储区
75、中。(10)写命令)写命令W(Write),有两种功能。,有两种功能。把数据写入磁盘的指定扇区。其格式为:把数据写入磁盘的指定扇区。其格式为:-W address drive sector sector把数据写入指定的文件中。其格式为:把数据写入指定的文件中。其格式为:-Waddress(11)退出)退出DEBUG命令命令Q(Quit),其格式为:,其格式为:-Q它退出它退出DEBUG,返回,返回DOS。本命令并无存盘功能,如需。本命令并无存盘功能,如需存盘应先使用存盘应先使用W命令。命令。4.4 4.4 DOS与与BIOS的调用的调用系统功能调用系统功能调用由由OSOS提供的一组实现特殊功能
76、的子程提供的一组实现特殊功能的子程序供程序员在程序中调用,以减轻编程工作量。序供程序员在程序中调用,以减轻编程工作量。系统功能调用系统功能调用有有两种两种, 一种称为一种称为DOS(Disk Operation System)功能调用功能调用 一种称为一种称为BIOS (basic input/output system) 功能调用功能调用用户程序用户程序在在调用这些系统服务程序调用这些系统服务程序时,时,不是不是用用CALL命命令令,而是采用而是采用软软中断指令中断指令INT n来来实现实现。在在DOS系统系统中,功能调用都是用软中断指令中,功能调用都是用软中断指令INT 21H来来实现的。
77、实现的。操作系统:用以控制和管理计算机硬件资源,方便用户使操作系统:用以控制和管理计算机硬件资源,方便用户使用的程序的集合。用的程序的集合。 MS-DOS 命令行式的界面命令行式的界面 WINDOWS采用图形式界面采用图形式界面用户程序用户程序磁盘管理模块磁盘管理模块(DOS内核内核)MSDOS.SYS 系统功能系统功能基本输入基本输入/输出输出 BIOS 模模 块块IO.SYS 设备驱动设备驱动ROM BIOS 基本基本I/O系系 统统 硬硬 件件装装入入命令处理模块命令处理模块COMMAN D.COM用户命令用户命令lROM BIOS中的中断子程序中的中断子程序 使用使用IN/OUT指令直
78、接控制外设,指令直接控制外设, 实现与外设之间的输入实现与外设之间的输入/输出操作输出操作 以软件形式向其上层提供服务。以软件形式向其上层提供服务。l中的中断子程序序中的中断子程序序 ( 称基本输入称基本输入/输出输出BIOS模模块块) 调用调用ROM BIOS的基本的基本I/O功能,向功能,向提供设备驱动服务。提供设备驱动服务。l 中的中断子程序中的中断子程序(称称DOS内内核模块核模块)调用调用IO.SYS,实现对外设控制实现对外设控制其中其中21H类型的中断子程序提类型的中断子程序提供了丰富的系统服务,称供了丰富的系统服务,称21H类型的中断调用为类型的中断调用为DOS系统系统(功能功能
79、)调用。调用。l 用户编程原则用户编程原则应用高级语言的应用高级语言的I/O语句语句尽尽可可能能使使用用DOS的的系系统统功功能能调用调用,提高程序可移植性。提高程序可移植性。在在DOS功功能能不不能能实实现现情情况况下下, 考虑用考虑用BIOS功能调用。功能调用。在在DOS和和BIOS的的中中断断子子程程序序 不不能能解解决决问问题题时时,使使用用IN/OUT指令直接控制硬件。指令直接控制硬件。用户程序用户程序磁盘管理模块磁盘管理模块(DOS内核内核)MSDOS.SYS 系统功能系统功能基本输入基本输入/输出输出 BIOS 模模 块块IO.SYS 设备驱动设备驱动ROM BIOS 基本基本I
80、/O系系 统统 硬硬 件件装装入入命令处理模块命令处理模块COMMAN D.COM用户命令用户命令4.4.2 系统功能调用系统功能调用 系统功能调用是系统功能调用是IBM PC微机系统为汇编用户提供微机系统为汇编用户提供的一个程序接口。的一个程序接口。DOS系统的软中断处理程序系统的软中断处理程序MS-DOS下进行的。下进行的。主要功能:主要功能: 1、磁盘的读、磁盘的读/写控制写控制 2、内存的管理、文件操作和目录管理、内存的管理、文件操作和目录管理 3、基本输入、基本输入/输出输出(对键盘、打印机和显示器控制对键盘、打印机和显示器控制)、日期、时间等。日期、时间等。一、一、DOS软中断调用
81、软中断调用设置入设置入口参数口参数INT n自动自动 IRET分析、应用分析、应用出口参数出口参数 调用方法调用方法设置入口参数设置入口参数在在AH设置功能号设置功能号m执行中断指令执行中断指令INT N分析、应用出口参数分析、应用出口参数为了使用方便,系统已将所有子程序按顺序编号,称为调用号。其调用号为075H。对于所有的功能调用,使用时一般需要经过以下三个步骤:(1)子程序的入口参数送相应的寄存器。(2)子程序编号送AH。(3)发出中断请求:INT21H(系统功能调用指令)。键盘和显示器的键盘和显示器的DOS调用调用 调用号用号功功 能能入入 口口 参参 数数出出 口口 参参 数数1键入并
82、入并显示一示一个字符个字符键入字符的入字符的ASCII码在在AL中中2显示器示器显示一示一个字符个字符DL中置中置输出字符出字符的的ASCII码5打印机打印一打印机打印一个字符个字符DL中置中置输出字符出字符的的ASCII码8键盘输入一个入一个字符字符键入字符的入字符的ASCII码在在AL中中9显示器示器显示一示一个字符串个字符串DS:DX置字符串置字符串首址,字符串以首址,字符串以$结束束10(0AH)键入并入并显示字示字符串符串DS:DX置字符置字符串首址,第串首址,第1单元置元置允允许键入的字符数入的字符数(含一个回含一个回车符符)DS:DX第一个字节能容纳的字符个数,不为零; 第二个字
83、节保留,以用填写实际输入的字符数 第三个字节开始存放从键盘上接收的字符串。11(0BH) 检测有无有无键入入有有键入入ALFFH,无无键入入AL0例如,显示一个字符串Goodmorning!的程序如下:MSGDBGoodmorning!$MOVDX,OFFSETMSG;字符串首字符的偏移地址送DXMOVAH,9;功能号9送AHINT21H;系统功能调用有的子程序不需要入口参数,这时步骤(1)可以略去。例如:MOVAH,4CH;功能号4CH送AH(返回DOS子程序)INT21H1)1号功能调用(键入并显示一个字符键入并显示一个字符)调用格式:MOV AH,1INT21H系统执行该功能时将扫描键盘
84、,等待键入。一旦有键按下,就将键值(相应字符的ASCII码值)读入,先检查是否是CtrlBreak。若是,则退出命令执行;否则将键值送入AL寄存器,同时将这个字符显示在屏幕上。例:程序中有时需要用户对提示做出应答。 GET_KEY: MOV AH,1;等待键入字符 INT 21H;结果在AL中 CMP AL,Y ;是Y? JZ YES ;是,转YES CMP AL,N ;是N? JZ NO ;是,转NO JMP GET_KEY;否则继续等待输入 YES: NO: 2)2号功能调用(显示器显示一个字符显示器显示一个字符)调用格式:MOVDL,待显示字符的ASCII码MOVAH,2INT21H本调
85、用执行后,显示器显示其ASCII码值放入DL中的字符。3)9号功能调用(显示器显示一个字符串显示器显示一个字符串)调用格式:MOVDX,待显示字符串首字符的偏移地址MOVAH,9INT21H本调用执行后,显示器显示待显示的字符串。调用时,要求DS:DX必须指向内存中一个以“$”作为结束标志的字符串。例如:DATASEGMENTBUFDBHOWDOYOUDO?$DATAENDSCODE SEGMENTMOVAX,DATAMOVDS,AXMOVDX,OFFSETBUFMOVAH,9INT21HCODE ENDS4) 输入字符串(功能号功能号=0AH=0AH) 此功能调用从键盘输入一串字符并把它存入
86、用户指定的缓冲区中。 MOV AH,MOV AH, 0AH0AH LEA DX, LEA DX, INT 21H INT 21H (预留的预留的N1个字节的存储单元个字节的存储单元) 0DHN2N1 N1: 缓冲区长度缓冲区长度(最大键入字符数最大键入字符数) N2: 实际键入的字符数实际键入的字符数(不包括回车符不包括回车符) 用户定义的输入字符串的缓冲区格式 DATASEGMENTBUFDB50;数据区长度DB?;保留,填入实际输入的字符个数DB50DUP(?);定义50个字节存储空间DATAENDSCODESEGMENTMOVDX,OFFSETBUFMOVAH,10INT21HCODE
87、ENDS5)0BH号功能调用(检查键盘工作状态检查键盘工作状态)调用格式:MOV AH,0BHINT21H 有键入有键入ALFFH,无键入,无键入AL0例如:按任意按键返回DOSLOP: MOV AH,0BH INT 21H ADD AL,01H JNZ LOP MOV AH,4CH INT 21H DOS在转移控制权时,将在转移控制权时,将CS指向指向EXE程序的代程序的代码段,码段,SS指向堆栈段,指向堆栈段,DS和和ES并不指向用户程序的并不指向用户程序的数据段和附加数据段而是指向数据段和附加数据段而是指向PSP,这样便于用户使,这样便于用户使用和处理用和处理PSP中的信息。所以在初始化
88、程序中有将数中的信息。所以在初始化程序中有将数据段的段地址送据段的段地址送DS的两条指令的两条指令(若有附加数据段,还若有附加数据段,还应有将附加段的段地址送应有将附加段的段地址送ES的指令的指令): MOV AX,DATA MOV DS,AX DOS像调用子程序一样,调用像调用子程序一样,调用EXE程序,程序,EXE程程序执行后也应像子程序返回调用程序一样返回序执行后也应像子程序返回调用程序一样返回DOS。 DOS为为EXE程序返回程序返回DOS安排了两种方法:安排了两种方法: (1)用调用号为用调用号为4CH的系统功能调用的系统功能调用 4CH功能调用返回功能调用返回DOS虽简单,但不论是
89、什么程虽简单,但不论是什么程序调用它均返回序调用它均返回DOS。(2)用软中断指令用软中断指令 INT 20H。 INT 20H返回调用程序要求返回调用程序要求CS指向指向PSP。只能利。只能利用远过程中的返回指令能将堆栈中的用远过程中的返回指令能将堆栈中的PSP的首地址送的首地址送给给CS和和IP,然后执行放在,然后执行放在PSP首地址中的首地址中的INT 20H指指令,从而使令,从而使EXE程序结束返回调用程序。程序段为:程序结束返回调用程序。程序段为: PUSH DS ;PSP的段地址进栈的段地址进栈 SUB AX,AX PUSH AX ;PSP首偏移地址进栈首偏移地址进栈 RET ;P
90、SP的首地址出栈的首地址出栈 综上述可知,执行初始化程序的作用其一是使综上述可知,执行初始化程序的作用其一是使PSP的首地址进栈,以便远返回指令结束用户程序返的首地址进栈,以便远返回指令结束用户程序返回调用程序,其二是使回调用程序,其二是使DS指向数据段的段首址。指向数据段的段首址。2常用系统功能调用应用举例常用系统功能调用应用举例利用DOS系统功能调用实现人机对话。例1:下述程序可以在屏幕上显示一行提示信息,然后接收用户从键盘输入的信息并将其存入内存数据区。DATASEGMENTPARSDB100;定义输入缓冲区DB?DB100DUP(?)MESGDBWHATISYOURNAME?;要显示的
91、提示信息DB$;提示信息结束标志DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,START: MOV AX,DATA MOV DS,AX DISP: MOV DX,OFFSET MESG MOV AH,9 ;利用9号功能调用显示提示 INT 21H KEYBD:MOV DX,OFFSET PARS MOV AH,10;利用10号功能调用接收键盘输入 INT 21H MOV AH,4CH INT 21HCODE ENDSEND例2编写汇编语言源程序,将键入的4位十进制数(如5,则键入0005)以压缩BCD数形式存入字变量SW中。该程序首先接收键入的4位十进
92、制数,然后拼合为压缩BCD数,存入字变量SW。为了接收键入的4位十进制数,需要在数据段中定义一变量数据区。该数据区应有7个字节,其中第1字节定义为5,即可接收5个字符,第2字节预留给10号功能调用装载实际键入的字符数,第3字节到第7字节预留给10号功能调用装载实际键入的字符,即4字节十进制数的ASCII码和1字节回车的ASCII码。程序如下:DATASEGMENT BUFDB 5,0,5 DUP (?)SW DW ?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOVAX,DATAMOV DS,AXMOV DX,OFFSETBUF;10号功
93、能调用,键入4位十进制数MOVAH,10INT 21HMOVAX,WORDPTRBUF+4;键入数的个位和十位送AXANDAX,0F0FH;将两个ASCII码转为非压缩BCD数MOV CL,4 SHL AL,CL ;将十位移至AL的高4位 OR AL,AH ;十位和个位拼合在AL中 MOV BYTE PTR SW,AL ;存BCD数的十位和个位 MOV AX,WORD PTR BUF+2 ;键入数的百位和千位送AXAND AX,0F0FH ;将两个ASCII码转为非压缩BCD数SHL AL,CL ;将千位移至AL的高4位OR AL,AH ;千位和百位拼合在AL中MOV BYTE PTR SW+
94、1,AL ;存BCD数的千位和百位CODE ENDS END START 3. BIOS中断调用BIOS是固化在ROM中的一组I/O驱动程序,它为系统各主要部件提供设备级控制,还为汇编语言程序设计者提供了字符I/O操作。与DOS功能调用相比,BIOS有如下特点:调用BIOS中断程序虽然比调用DOS中断程序要复杂一些,但运行速度快,功能更强;DOS的中断功能只是在DOS环境下适用,而BIOS功能调用不受任何操作系统的约束;某些功能只有BIOS具有。1)键盘服务程序键盘服务程序的中断类型号为16H,用INT16H调用。软中断INT16H服务程序有三个功能,功能号分别为0、1、2,功能号及出口参数如
95、表所示。表5.5INT16H的功能功功 能能 号号功功 能能出出 口口 参参 数数0从从键盘读字符字符键入字符的入字符的ASCII码在在AL中中1检测键盘是否是否键入字符入字符键入字符入字符ZF=0,未,未键入字符入字符ZF=12读键盘各各转换键的当前状的当前状态各各转换键的状的状态在在AL中中2)打印机服务程序打印机服务程序的中断类型号为17H,用INT17H调用。软中断INT17H服务程序有三个功能,功能号为0、1、2,其中打印一字符的功能号为0,入口参数是将打印字符的ASCII码送AL,打印机号02送DX。3)显示器服务程序显示器服务程序的中断类型号为10H,用INT10H调用。软中断I
96、NT10H服务程序有16个功能,功能号为015。常用功能如表所示。表中的“显示方式”有7种,如表所示。表中的显示属性是字符方式下字符的显示属性,由一个字节定义,由它来设置字符和背景的颜色。显示属性字节如图所示。其中背景颜色和字符颜色如表所示。表表5.6 INT 10H的功能的功能 图5.5显示属性字节表表5.7 显示方式显示方式 AL值显示方式04025黑白字符方式14025彩色字符方式28025黑白字符方式38025彩色字符方式4320200黑白图形方式5320200彩色图形方式6640200黑白图形方式78025单色字符方式表表5.8 字符颜色字符颜色 RGB背景色或正常亮度字符色高亮度字
97、符色000黑灰001蓝浅蓝010绿浅绿011青蓝浅青蓝100红浅红101品红浅品红110棕黄111白高亮度白黑白字符方式下字符的显示属性仅为黑或白(灰或高亮度白)。图形方式的颜色设置与字符方式不同,其颜色不用显式属性字节来设置。设置的方法是用功能号11设置背景颜色,用功能号11和12设置像点颜色。背景颜色有16种,编号为015,其颜色是彩色字符方式下正常亮度和高亮度字符颜色的组合,即0为黑色,1为蓝色,15为高强度白色。像点的颜色只有6种,由彩色组和彩色值来选择,如表所示。表表5.9 像点颜色像点颜色 彩色值彩色组0彩色组11绿青2红品红3黄白 在屏幕的13行40列位置显示高亮度闪动的“太阳”
98、。程序如下:STACK SEGMENTSTACKSTACKDW32DUP(?)STACKENDSCODE SEGMENTASSUMESS:STACK,CS:CODESTART:MOVAX,STACKMOVSS,AXMOV AH,7;8025单色字符方式MOV AL,2INT10HMOV AH,15;读取显示页号INT10HMOV AH,2;设置光标位置MOV DX,0D28HINT10HMOV AH,9;高亮度白闪烁的太阳MOV AL,0FHMOV BL,8FHMOV CX,1INT10HMOVAH,4CH;返回DOSINT21HCODE ENDSENDSTART4.5 4.5 汇编语言程序设
99、计汇编语言程序设计4.5.1 4.5.1 概述概述程序质量1、运行结果正确2、良好的结构,清晰易读3、执行速度快4、占用空间少结构化程序1、采用模块化(每个模块只有一个入口和出口)2、可控制的使用无条件转移语句3、采用自顶向下的、逐步细化和逐步求精的方法开发程序。汇编语言程序设计的步骤: 1-1-根据实际问题抽象出数学模型根据实际问题抽象出数学模型 2- 2-确定算法确定算法 3- 3-画出程序框图画出程序框图( (流程图流程图) ) 4- 4-分配内存工作单元和寄存器分配内存工作单元和寄存器 8- 8-运行、调试运行、调试源程序的基本结构:顺序、分支、循环、过程 (1)用方框表示工作框,框中
100、用简明语言标明要完成的功能(2) 用菱形框表示判断框 框中标明比较、判断和条件如何绘制程序框图(流程图)?NY?(4)各框之间用直线连起来表示程序走向。框中标明子程序名字(入口参数等)(3)(3)用用 框表示调用子程序或过程框表示调用子程序或过程。 汇编语言上机过程汇编语言上机过程YYYNNN有错?有错?有错?结束汇编输入(修改)源程序连接运行查错开始用EDIT,NOTEPAD等任何文本编辑器。源程序存为.ASM文件 用MASM宏汇编程序进行汇编。汇编后生成.OBJ目标文件。命令格式:MASM ; 用LINK连接程序进行连接。连接后生成.EXE可执行文件。命令格式:LINK ; 用TD、DEB
101、UG等调试程序进行调试。命令格式:TD 4.5.4 4.5.4 程序的基本结构与基本程序设计程序的基本结构与基本程序设计一、顺序程序一、顺序程序初始化初始化顺序程序顺序程序.标号:条件满足条件满足?处理处理二、分支程序二、分支程序NYIFTHEN结构程序结构: 测试/比较指令 (TEST/CMP) 条件转移指令 (Jx 标号) 处理体处理体 标号: 其他指令 程序结构: TEST/CMP指令 Jx 标号1 处理体处理体P1 JMP 标号2标号1: 处理体处理体P2标号2:其他指令 条件满足条件满足?处理处理P1处理处理P2标号1:标号2:条件1条件2IFTHENELSE结构标号标号1:条件条件
102、1成立成立?P1NYCASE结构程序结构:程序结构: TEST/CMP指令(测试条件1) Jx 标号1 ;不满足转标号1 处理体处理体P1 JMP 标号标号n+1标号1:TEST/CMP指令(测试条件2) Jx 标号2 ;不满足转标号2 处理体处理体P2 JMP 标号标号n+1标号2:TEST/CMP指令(测试条件3) Jx 标号3 ;不满足转标号3 处理体处理体P3 JMP 标号标号n+1标号3:TEST/CMP指令(测试条件4) 标号n+1:(公共出口)条件条件2成立成立?条件条件n成立成立?Pn+1标号标号2:标号标号n:标号标号n+1:P2PnNNYY三、 循环程序1DOUNTIL 结
103、构 先执行,再判断条件。工作部分至少执行一次。初始化初始化循环体循环体循环控制循环控制继续循环?继续循环?YN2. DO WHILE 结构先判断条件,再执行。工作部分有可能一次都不执行。初始化初始化循环体循环体循环控制循环控制继续循环?继续循环?YN掌握以下几点:调用子程序用CALL指令,返回调用程序用RET指令。子程序允许嵌套调用。进入子程序后首先要保护主程序的运行状态(标志位)和使用的寄存器内容(称为保保护护现现场场),退出子程序前要恢复现场恢复现场。调用前要预先确定子程序中要使使用用哪哪些些寄寄存存器器,并定定义义入入口口参参数数和和出出口口参参数数。参数传递可利用寄存器、存储单元或堆栈
104、(要用BP寻址)。四、四、 子程序设计举例子程序设计举例一、顺序程序举例1、运算程序例计算Z=(X*Y-3*Y)/2的程序。X、Y为字节,Z为一个字。Z=(X*Y-3*Y)/2DATA SEGMENT X DB 25 Y DB 32 Z DW ?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV AL,X MUL AL MOV BX,0 MOV BL,Y ADD BL,BL ADC BH,0 ADD BL,Y ADC BH,0 SUB AX,BX SHR AX,1 MOV Z,AX MOV AH
105、,4CH INT 21HCODE ENDS END start开始开始 结束结束 X*YY+Y+YXY-3Y(XY-3Y)/2存结果存结果存结果存结果2、查表程序例查表求平方TABLE开始的16字节单元存放0-15平方,任意给定X字节,求其平方存入YD中。DATA SEGMENT XD DB ? YD DB ? TABLE DB 0,1,4,9,16,25,36,49, DB 64,81,100,121,144,169,225DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV BX,OFFSET
106、 TABLE MOV AH,0 MOV AL,XD XLAT MOVYD,AL MOV AH,4CH INT 21HCODE ENDS END START51H64H79H90HA9HE1H06H07H08H09H10H40H31H24H19H10H09H04H01H00HTABLE+1TABLE+0YDXDDS05H19HADD BX,AXMOV AL,BX例:输入大写字母转换成小写字母DATA SEGMENT s_input DB please input A-Z:,$ S_OUT DB 0AH,0DH,convert result:$ exit1 DB 0AH,0DH,PRESS ANY
107、 KEY TO EXIT!$ NUM EQU 20HDATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXAGAIN: LEA DX,S_INPUTMOV AH,09HINT 21H MOV AH,01HINT 21HCMP AL,41H;JL AGAINCMP AL,5AHJG AGAIN PUSH AX LEA DX,S_OUT MOV AH,9 INT 21HPOP AX MOV DL,NUMADD DL,ALMOV AH,2INT 21HLEA DX,EXIT1MOV AH,09HINT 21HLO
108、P: MOV AH,0BHINT 21HADD AL,01HJNZ LOPMOV AH,4CHINT 21HCODE ENDSEND START二、分支程序结构二、分支程序结构两路分支 程序中使用一条条件转移指令实现两路分支三路分支 用两条以上指令进行分支程序设计多路分支 采用转移地址表或转移指令表的形式1、两路分支在以在以BLOCK开始的存储区域内存放着开始的存储区域内存放着100个字节的个字节的8位位带符号数,在该存储区域内找出其中最大的数和最小的带符号数,在该存储区域内找出其中最大的数和最小的数,分别放在数,分别放在MAX和和MIN单元中,编程实现。单元中,编程实现。NAME FOUND
109、 DATA SEGMENT BUF DB -2,+5,.,-128 ;定义定义100个字节数据个字节数据 DB +127,80,.,-70 ; COUN EQU $-BUF ;数据个数数据个数 MAX DB ? ;放最大值的存储单元放最大值的存储单元 MIN DB ? ;放最小值的存储单元放最小值的存储单元 DATA ENDS ;数据段结束数据段结束;. STACK SEGMENT STACK;堆栈区定义堆栈区定义 STR DB 64H DUP(?) ;堆栈区占堆栈区占64个单元个单元 STACK ENDS;. MYCODE SEGMENT ;代码段代码段 ASSUME DS:MYCODE,D
110、S:DATA,SS:STACK START: MOV AX,DATA ; MOV DS,AX ;DS赋初值赋初值 MOV AX,STACK ; MOV SS,AX ;SS赋初值赋初值 MOV SP,LENGTH STR ;设堆栈指针设堆栈指针00H01H02H03H04H05H06H07H08H09H10H?BAH06H77H66HA5H05HFEH05HMINMAXBUF+99BUF开始开始 设置循环次数设置循环次数设置地址指针设置地址指针将第一个数放入将第一个数放入大数寄存器大数寄存器和小数寄存器和小数寄存器修改指针修改指针取数据入取数据入大数寄存器大数寄存器大数寄存器大数寄存器与数据比较
111、与数据比较Y Y结束结束 小数寄存器小数寄存器与数据比较与数据比较N N取数据入取数据入小数寄存器小数寄存器存结果存结果循环结束否 MOV CX,COUN-1 ;实际比较次数实际比较次数 MOV SI,OFFSET BUF ;建立地址指针建立地址指针 MOV AL,SI ;取第一个数放取第一个数放AL中中 ;大数放大数放AL内内 MOV BL,SI ;取第一个数放取第一个数放BL中中 ;小数放小数放BL内内 INC SI ;LOP: CMP AL,SI ; JGE NEXT1 ;AL=下一个数下一个数,不交换不交换 MOV AL,SI ;否则交换否则交换,大数在大数在AL中中NEXT1:CMP
112、 BL,SI ;最小数与下一单元数比较最小数与下一单元数比较 JL NEXT ;最小值比较小最小值比较小 ;BL00=0开始开始 结束结束 NAME EXE-4 DATA SEGMENT DATX DB -3 DATY DB ? DATA ENDS;. CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA ; MOV DS,AX ; MOV AL,DATX ; CMP AL,0 ; JGE BIGER ; MOV AL,0FFH ;X0,1送送DATY单元单元 JMP NEXT EQUL: MOV DATY,AL ;X=0,0送送DATY
113、单元单元 NEXT: MOV AH,4CH INT 21H;. CODE ENDS END START 、多路分支采取利用跳转表实现CASE结构ARTABR0R0低字节低字节低字节低字节R0R0高字节高字节高字节高字节R1R1低字节低字节低字节低字节R1R1高字节高字节高字节高字节R2R2低字节低字节低字节低字节R2R2高字节高字节高字节高字节R3R3低字节低字节低字节低字节R3R3高字节高字节高字节高字节R4R4低字节低字节低字节低字节R4R4高字节高字节高字节高字节R9R9低字节低字节低字节低字节R9R9高字节高字节高字节高字节0000000000DS查表求地址查表求地址AXBX+2iAX
114、=?i=0i=1i=n;假定有10种处理子程序,分别存放在以R0、R1、.、R9为首地址的内存区域中,这10个入口地址(即起始地址或首地址)的偏移地址连续存;放在以ADRTAB为首地址的跳转表内,入图所示。;跳转表建立后,利用跳转表进行选择,转移到10个不同的子程序。当键入“0”“9”10个数字符号其中之一时,就转向不同的分支。程序流;程图如图。程序如下:NAME EXE-5 DATA SEGMENTADRTAB DW R0,R1,R2,R3 DW R4,R5,R6,R7,R8,R9 ; TEN DB ? DATA ENDS STACK SEGMENT PARA STACK STACK STA
115、 DB 100 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK START:MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV SP,LENGTH STA;.ARTABR0R0低字节低字节低字节低字节R0R0高字节高字节高字节高字节R1R1低字节低字节低字节低字节R1R1高字节高字节高字节高字节R2R2低字节低字节低字节低字节R2R2高字节高字节高字节高字节R3R3低字节低字节低字节低字节R3R3高字节高字节高字节高字节R4R4低字节低字节低字节低字节R4R4高字节高字节
116、高字节高字节R9R9低字节低字节低字节低字节R9R9高字节高字节高字节高字节0000000000DS MOV AH,01 INC 21H ;扫描键盘 ;输入字符放入AL COMPUT:MOV AH,0 AND AL,0FH ;屏蔽高4位 ADD AL,AL ;AL值乘以2 MOV BX,OFFSET ADRTAB ADD BX,AX MOV AX,BX ;取入口地址 JMP AX;. RO: . ;第0号处理程序 R1: sub10: sub11: . ;. ;. ;. R9: . MOV AH,4CH INC 21H CODE ENDS END START ARTABR0R0低字节低字节低字
117、节低字节R0R0高字节高字节高字节高字节R1R1低字节低字节低字节低字节R1R1高字节高字节高字节高字节R2R2低字节低字节低字节低字节R2R2高字节高字节高字节高字节R3R3低字节低字节低字节低字节R3R3高字节高字节高字节高字节R4R4低字节低字节低字节低字节R4R4高字节高字节高字节高字节R9R9低字节低字节低字节低字节R9R9高字节高字节高字节高字节0000000000DS查表求查表求地址地址AXBX+2iAX=?i=0 i=1i=n MOV AH,01 INC 21H ;扫描键盘 ;输入字符放入AL COMPUT:MOV AH,0 AND AL,0FH ;屏蔽高4位 ADD AL,A
118、L ;AL值乘以2 mov si,ax MOV BX,OFFSET ADRTAB JMP word ptr bx+si ;. RO: . ;第0号处理程序 R1: . ;. ;. ;. R9: . MOV AH,4CH INC 21H CODE ENDS END START ARTABR0R0低字节低字节低字节低字节R0R0高字节高字节高字节高字节R1R1低字节低字节低字节低字节R1R1高字节高字节高字节高字节R2R2低字节低字节低字节低字节R2R2高字节高字节高字节高字节R3R3低字节低字节低字节低字节R3R3高字节高字节高字节高字节R4R4低字节低字节低字节低字节R4R4高字节高字节高字节
119、高字节R9R9低字节低字节低字节低字节R9R9高字节高字节高字节高字节0000000000DS查表求查表求地址地址AXBX+2iAX=?i=0 i=1i=n三、循环程序结构及其设计循环程序并不节省时间,但节省空间控制结构分,当型和直到型初始化初始化循环体循环体循环控制循环控制继续循环?继续循环?YN初始化初始化循环体循环体循环控制循环控制继续循环?继续循环?YNDOUNTIL 结构DO WHILE 结构还可以分成单循环和多重循环初始化初始化内循环体内循环体内循环控制内循环控制继续内循环?继续内循环?YN外循环体外循环体内循环控制内循环控制继续内循环?继续内循环?YN1、单重循环1)单循环次数未
120、知例4.15 字单元X中的1的个数DATA SEGMENTX DW 31A0HRESULT DW ?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX MOV CX,0 ;初始化初始化CX=0 MOV AX,X ;取取X到到AXAGAIN:AND AX,AX ;X=0?多种!?多种! JZ EXIT ;X=0,退出,退出 SHL AX,1 JNC NEXT ;(CF)=1 INC CX ;是,计数是,计数 NEXT:JMP AGAINEXIT: MOV RESULT,CX ;存结果存结果 MOV AH
121、,4CH INT 21H ;返回返回DOS CODE ENDS END START初始化初始化CXAXXRESULTCXAX=0?YNCF=1?AX左移左移1位位CXCX+1NY开始开始结束结束2)单循环单循环 次数已知次数已知内存BLOCK开始连续存放10个数据,每个数据都是16位带符号数,求其累加和 ,和存入SUM单元(和不大于16位),编程实现。NAME EXE-7DATA SEGMENTBLOCK DW 0028H,0FF18H,1005H,7823H,0 DW 0CDABH,0FFFFH,1122H,3344H,7892HCOUN EQU ($-BLOCK)/2SUM DW ?DAT
122、A ENDSSTACK SEGMENT PARA STACK STACKSTA DW 100 DUP(?)TOP EQU SIZE STASTACK ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOV AX,DATA ;初始化初始化DS MOV DS,AX MOV AX,STACK ;初始化初始化SS MOV SS,AX MOV SP,TOP ;建立堆栈指针建立堆栈指针CDHFFHFFH92H78H0AH00H?ABH00H00H78H23H10H05HFFH18H00H28HSUMCOUNBLOCK+12HBLOCKDS开始开始
123、结束结束初始化初始化和寄存器清零和寄存器清零设置地址指针设置地址指针设置循环次数设置循环次数循环体循环体和寄存器与和寄存器与所取数据相加所取数据相加修改地址指针修改地址指针循环结循环结束否?束否?YNMOV AX,0 ;AX放累加和,开始清放累加和,开始清0MOV SI,OFFSET BLOCK ;建立地址指针建立地址指针MOV CX,COUN;设计数值设计数值LOP: ADD AX,SI ;加上一个数加上一个数 inc si ;修改指针修改指针 inc si LOOP LOP ;CX减减1,不为,不为0转转LOP MOV SUM,AX ;存和存和 MOV AH,4CH INT 21HCODE
124、 ENDS END STARTCDHFFHFFH92H78H0AH00H?ABH00H00H78H23H10H05HFFH18H00H28HSUMCOUNBLOCK+12HBLOCKDS开始开始结束结束初始化初始化和寄存器清零和寄存器清零设置地址指针设置地址指针设置循环次数设置循环次数循环体循环体和寄存器与和寄存器与所取数据相加所取数据相加修改地址指针修改地址指针循环结循环结束否?束否?YN2、多重循环。、多重循环。 软件延时程序。由于每条指令的执行所需要T状态数是固定的,可以用多重循环的方法,实现固定的延时。本程序中假定f=10MHZ,时钟周期t=0.1s,即T状态为s. TIMEDLY P
125、ROC ;指令的T状态数 MOV BX,100 ;4 DELAY:MOV CX,5882 ;4 DELAY0:LOOP DELAY0 ;17/5(转移17T) DEC BX ;2 JNZ DELAY ;16/4(转移16T) RET ;8 TIMEDLY ENDP17*(5882-1)+517*(5882-1)+5+4+2+16*100-12+8+434H34H34H34H34H34H例 4.18 关于排序程序(冒泡程序)有N个连续存于内存中,要求其按一定次数排列。假设8个单元,排列后要求大数在下08H06H09H14H13H12H34H00H06H09H14H13H12H00H08H06H0
126、9H14H13H12H34H00H08H34H08H06H09H14H13H12H34H00H08H06H09H14H13H12H34H00H08H06H09H14H13H12H34H00H08H06H09H14H13H12H34H00H内循环N-1次,外循环也为N-1次可设一交换标志提前退出外循环也可以做外循环的退出条件外循环也为N-1次,内循环每次外循环次数,外循环和内循环次数相等NAME ABC-PROGRAMDATASEG SEGMENTARRAY DW 1234H,5437,7FFFH DW 0FFFFH,0AB55H,05FFH DW 7823H,0,9043H,5634COUN
127、EQU ($-ARRAY)/2DATASEG ENDSSTACKSEG SEGMENT PARA STACK STACKSTAPN DB 100 DUP(?)TOP EQU LENGTH STAPNSTACKSEG ENDSPROGRAM SEGMENT ASSUME CS:PROGRAM,DS:DATASEG,SS:STACKSEGSTART: MOV AX,DATASEG MOV DS,AX MOV AX,STACKSEG MOV SS,AX MOV AX,TOP MOV SP,AXDS05H23H78H00H00H43H90H34H56H0AHFFHABH55HFFHFFH7FHFFH5
128、4H37H12H34HCOUNARRAY+18ARRAY+16ARRAY+14ARRAY+12ARRAY+10ARRAY+8ARRAY+6ARRAY+4ARRAY+2ARRAY+000H MOV BL,0FFH A1: CMP BL,0FFH JNE A4 XOR BL,BL;内循环初始化 MOV CX, COUNT-1 XOR SI,SI A2: MOV AX,ARRAYSI CMP AX,ARRAYSI+2 JLE A3;由小到大排列 XCHG ARRAYSI+2,AX MOV ARRAYSI,AX MOV BL,0FFH A3: INC SI;修改指针 INC SI LOOP A2;内循
129、环是否结束 JMP A1 A4: MOV AH,4CH INT 21H PRCGRAM ENDS END STARTMOV CX, DX; MOV DX, COUNT-1DEC DX开始开始结束结束外循环初始化外循环初始化置有交换标志置有交换标志交换数据交换数据置交换标志置交换标志有交换否?有交换否?内循环初始化内循环初始化清交换标志清交换标志设地址位移指针设地址位移指针设内循环次数设内循环次数Y前前后后数据?数据?NYN修改指针修改指针内循环完?内循环完?YN05H23H78H00H00H43H90H34H56H0AHFFHABH55HFFHFFH7FHFFH54H37H12H34HCOUN
130、ARRAY+18ARRAY+16ARRAY+14ARRAY+12ARRAY+10ARRAY+8ARRAY+6ARRAY+4ARRAY+2ARRAY+000H置外循环次数置外循环次数外循环次数入内循环次数外循环次数入内循环次数外循环次数外循环次数-1外循环外循环-1=0?YNJNZ A1 JGE A3;由大到小排列 四、子程序设计四、子程序设计1、基本概念、基本概念可把具有独立功能的程序段定义为子程序可把具有独立功能的程序段定义为子程序(子模块或过程子模块或过程),供,供其他程序调用,类似于其他程序调用,类似于C语言的函数。语言的函数。 主程序可以多次调用子程序主程序可以多次调用子程序 子程序调
131、用其它子程序称子程序嵌套子程序调用其它子程序称子程序嵌套 子程序调用其本身成为子程序递归子程序调用其本身成为子程序递归CALL SUB1CALL SUB1CALL SUB2RETCALLSUB2RET主程序子程序SUB1子程序SUB2RET子程序SUB2特点特点: 通用性通用性:具有共同性的操作和运算编成一个子程序具有共同性的操作和运算编成一个子程序 浮动性浮动性:可装入任何位置,而不影响其它程序的运行,即可装入任何位置,而不影响其它程序的运行,即具有可重定位性。不使用绝对寻址,而使用相对寻址指令。具有可重定位性。不使用绝对寻址,而使用相对寻址指令。 使用的方便性使用的方便性:便于调用,应有子
132、程序说明文档。便于调用,应有子程序说明文档。3、子程序应注意的问题、子程序应注意的问题 文档的写法 ;子程序名,子程序功能子程序名,子程序功能 ;入口参数入口参数:调用前应具备哪些调用前应具备哪些条件及设定什么样的参数条件及设定什么样的参数 ;出口参数出口参数:处理的结果是什么处理的结果是什么或在什么位置,以便后续处理或在什么位置,以便后续处理 ;是否调用其它子程序是否调用其它子程序 ;使用哪些寄存器。使用哪些寄存器。现场的保护和恢复现场的保护和恢复: 子程序中用子程序中用到的非出口参数的寄存器内容,以到的非出口参数的寄存器内容,以免破坏到主程序用到的信息。使用免破坏到主程序用到的信息。使用P
133、USH和和POP,成对出现,成对出现SUBRP PROC FAR PUSH AX PUSH BX PUSH CX PUSHF . POPF POP CX POP BX POP AX RET SUBPR ENDP 主程序与子程序参数传递的方法主程序与子程序参数传递的方法: (向工厂提供原料向工厂提供原料) 入口参数和出口参数一定是变化的量入口参数和出口参数一定是变化的量 寄存器:寄存器:(数量有限,方便数量有限,方便) 主程序调用前,将参数值主程序调用前,将参数值REG入入 REG入入子程序使用的,处理完结果子程序使用的,处理完结果REG出出 主程序调用后从主程序调用后从REG出中分析结果。出中
134、分析结果。 堆栈堆栈:(大量参数大量参数)PUSH 注意使用时绕过端点入栈的位置注意使用时绕过端点入栈的位置(要用BP寻址)。 即:返回时可用即:返回时可用RET N 腾出刚才的位置腾出刚才的位置 存储器的数据区:可以用寄存器间接寻址的形式给出存储器的数据区:可以用寄存器间接寻址的形式给出 参数表参数表: 主程序中建立一个参数表,连续单元中,按一定顺主程序中建立一个参数表,连续单元中,按一定顺序存入,子程序中按需要取出。序存入,子程序中按需要取出。TABPR DW ?;被加数的地址 DW ?;加数地址 DW ?;和地址寄存器传递参数 例;多字节BCD码加法程序;变量FIRST开始存放4个字节的
135、BCD码,作为被加数。变量SECOND开始存放4个字节的BCD码,作为加数。求二者之和,存放于SUM开始的存储单元;中(设其和也为四个字节)。设计程序,并把相加之和在CRT显示屏幕上显示。NAME MADDDATA SEGMENTFIRST DB 11H,22H,33H,44H ;定义被加数BCD码SECOND DB 55H,66H,77H,88H ;定义加数BCD码SUM DB 6 DUP(?) ;结果存放单元DATA ENDS;.STACK SEGMENT STACK STACKSTA DB 50 DUP(?)TOP EQU LENGTH STASTACK ENDS;.CODE SEGME
136、NT ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATASTART:MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,STACK MOV SS,AX MOV SP,TOP ;设立堆栈指针 MOV SI,OFFSET FIRST;被加数地址指针 MOV DI,OFFSET SUM ;存放和地址指针 MOV BX,OFFSET SECOND;加数地址指针 MOV CX,04H ;计数器,4个字节BCD码 CALL LMAD MOV SI,OFFSET SUM MOV CX,04H CALL DISPLAY MOV AH,4CH INT 21H
137、;.;子程序子程序LMAD:完成多个字节压缩:完成多个字节压缩BCD码加法运算码加法运算;入口参数:入口参数: SI作为被加数地址指针,指向起始单元作为被加数地址指针,指向起始单元; BX作为加数地址指针,指向起始单元作为加数地址指针,指向起始单元; DI作为相加之和地址指针,指向起始单元作为相加之和地址指针,指向起始单元; BCD码字节个数放入码字节个数放入CX中,中,BCD码存放顺序,低位在低地址码存放顺序,低位在低地址; 高位在高地址上高位在高地址上;出口参数:相加之和仍为出口参数:相加之和仍为BCD码码,放在放在DI为地址指针的连续单元中为地址指针的连续单元中;所使寄存器:所使寄存器:
138、SI,DI,BX,AL;.LMAD PROC NEAR CLD ;DF=0 增址增址 CLC ;CF=0 清清CFLD: LODSB ADC AL,BX DAA ;十进制调整十进制调整 STOSB ;存一个字节相加之和存一个字节相加之和 INC BX LOOP LD RETLMAD ENDP;.;.;DISPLAY:显示BCD码子程序;入口参数:SI作为存放BCD码的起始地址的地址指针; CX存放BCD码字节数;出口: BCD码显示在CRT屏幕上;所用子程序:2号系统功能调用;所用寄存器:AL,BL,AH,SI,DL;.DISPLAY PROC NEAR ADD SI,CX ;SI指向数据高位
139、 DEC SIAGAIN: PUSH CX MOV AL,SI ;取一个字节BCD码 MOV BL,AL ;暂存于BL DEC SI ;修改地址指针 AND AL,0F0H ;屏蔽低4位 MOV CL,04H SHR AL,CL ;右移4位 ADD AL,30H ;转化成ASCII码 MOV DL,AL ;2号系统功能调用 MOV AH,02H INT 21H MOV AL,BL ;取低位BCD码 AND AL,0FH ADD AL,30H MOV DL,AL ;ASCII码送DL MOV AH,02H POP CX LOOP AGAIN RETDISPLAY ENDPCODE ENDS EN
140、D START堆栈传递参数 例例4.20 已知数据段定义了两个数据区ARY1和ARY2,变量ARY1、ARY2 均为字节型无符号数,在程序中要求计算每个数组的累加和(假定其和小于16位),并分别存入SUM1和SUM2单元中。每个数组的数据段的数据个数假定为10个,每个数据字节型的8位不带符号数,设计程序实现。NAME CNTSUMSTACK SEGMENG STACK STACK ;堆栈段SPAE DB 100 DUP(?)POP EQU LENGTH SPAESTACK ENDSDATA SEGMENTARY1 DB 10 DUP(?) ;定义数组1SUM1 DW ? ;存累加和ARY2 D
141、B 10 DUP(?) ;定义数组2SUM2 DW ? ;存累加和DATA ENDS MAIN SEGMENT ASSUME CS:MAIN,DS:DATA,SS:STACKSTART: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV SP,POP MOV AX,SIZE ARY1 ; PUSH AX ;数据长度压入堆栈,入口参数1 MOV AX,OFFSET ARY1 ; PUSH AX ;变量便宜地址压入堆栈,入口参数2 CALL SUMAD ;调子程序 . ;主程序其他处理 MOV AX,SIZE ARY2 ;入口参数1 PUSH AX
142、MOV AX,OFFSET ARY2 ;入口参数2 PUSH AX CALL SUMAD MOV AH,4CH INT 21HMAIN ENDS;.;子程序SUMAD:完成多个单字节数据累加求和的子程序,;放在一个独立的代码段内;入口参数:数组个数放在(BP+14)对应的地址单元,; 数组起始地址(偏移地址)放在(BP+12)对应存储单元,; 利用堆栈区传送;出口参数:完成累加,其和16位,分别放SUM1和SUM2变量中;所用寄存器:AX,BX,CX,BP,SP,AH;.PROCROG SEGMENT ;过程代码段过程代码段 ASSUME CS:PROCROG,DS:DATA,SS:STACK
143、SUMAD PROC FAR PUSH AX ;保护现场保护现场 PUSH BX PUSH CX PUSH BP MOV BP,SP ;SP当前值放入当前值放入BP中中 PUSHF ;FLAG压入堆栈压入堆栈 MOV CX,BP+14;取出堆栈区存放的数组长度取出堆栈区存放的数组长度 MOV BX,BP+12;取出数组起始偏移地址取出数组起始偏移地址 MOV AX,0ADN: ADD AL,BX;累加累加 INC BX ;修改指针修改指针 ADC AH,0;加进位加进位 LOOP ADN MOV BX,AX POPF POP BP ;恢复现场恢复现场 POP CX POP BX POP AX
144、RET 4 ;返回并废除原压入参数,返回并废除原压入参数,SP恢复恢复 ;调用子程序前的调用子程序前的SP值,值,SP-SP+2,SP-SP+4 SUMAD ENDPPROCROG ENDS END START xxxxXXXXXXXXXXXXXXXX栈底栈底xxxxxxxxxxxxxxxxxxXX数组长度数组长度数组偏移地址数组偏移地址断点断点CS值值断点断点IP值值AXBXCXBPFLAGS SP SS例1:二进制数(0-F)转换成ASCII(0-F)的子程序。BIN2ASC PROC ;要转换的数在AL的低四位 ;转换结果仍在AL中 CMP AL, 9 JA A2F ADD AL, 30
145、H JMP DONE A2F: ADD AL, 37H DONE: RETBIN2ASC ENDP调用方法:(在主程序中) MOV AL, 0CH CALL BIN2ASC (AL中有0CH的ASCII码43H, C)例2. 字符串处理程序设计 对字符串进行操作时,往往需要确定它的长度。通常字符串结束标志以CR或$作标志。所以可以用扫描CR或$的方法计算出串长。 在计算串长时,应注意串长一般应小于255个字节。 以下是流程图和源程序。 简化的流程图:开始求串长求串长串长255,则结束CMPDI,AH;本字符是$?JEDONE ;是,则结束SCASBSCASB;本字符是CR?JNEAGAIN;未
146、找到,返回继续DONE:MOVLENGTH1,CX ;找到,LENGTH1串长RET;返回主程序STRLENSTRLENENDPENDP;- 子程序结束 -CODECODEENDSENDSENDBEGIN 十、二进制数、ASCII码之间的互相转换。BCD数数2进制数进制数 算法:Dn-1*10n-1+D0*100 = (Dn-1*10+ Dn-2)*10+)*10+ D0 = (0*10+Dn-1)*10+ Dn-2)*10+)*10+ D0 即: 新的中间结果 = 中间结果*10+本位数字 (中间结果初值为0)4.5 常见程序设计举例程序1:将65535的非压缩BCD数转换成2进制数。程序如
147、下。 ;数据段定义 mydata SEGMENT decnum DB 5, 3, 0, 1, 9 ;BCD数 53019 binnum DW ?mydata ENDSprog SEGMENT ASSUME CS:prog,DS:mydatabegin: MOV AX, mydata MOV DS, AX MOV SI, OFFSET decnum+4 MOV CX, 5 ;5位位BCD数数 MOV BX, 10 XOR AX, AX ;中间结果初始值为中间结果初始值为0Next: MUL BX ;中间结果中间结果*10+本位数字本位数字 ADD AL, SI ADC AH, 0 DEC SI
148、;指向下位指向下位BCD数数 LOOP next MOV binnum, AX ;保存结果保存结果 MOV AH, 4CH INT 21Hprog ENDS END begin程序2:把255的非压缩BCD数转换成2进制数 decnum DB 1,5,9 ;BCD数159 binnum DB ? MOV AX,decnum XCHG AH, AL ;百位在AH, 十位在AL AAD ;百位数*10 + 十位数 MOV AH, AL ;中间结果送AH MOV AL, decnum+2 AAD ;中间结果*10 + 个位数 MOV binnum, AL 例:从键盘输入两个整数例:从键盘输入两个整数
149、, ,并求其和。并求其和。 因键入为整数因键入为整数, ,故要进行如下转换:故要进行如下转换: ASCIIBCD ASCIIBCD二进制数二进制数 ASCIIBCD ASCIIBCD码很简单码很简单, ,高高4 4位清零即可得到非压位清零即可得到非压缩的缩的BCDBCD码。码。 BCD BCD二进制数在本例中采用用以下方法:二进制数在本例中采用用以下方法: ( (0+(0+千位数千位数)*10)*10+ +百位数百位数)*10)+)*10)+十位数十位数)*10+)*10+个位数个位数 ASCIIASCII码码二进制数二进制数( (用于输入用于输入) ) 第一次中间结果第二次中间结果第三次中间
150、结果最终结果开始开始两个数分别转换成二进制数键入两个数键入两个数相加相加结束结束返回返回DOS如有溢出则提示如有溢出则提示开始取第一个ASCII码是负号吗?数字符个数1,指针1指针定位字符个数1=0?取数字,与中间结果相加,再乘以10指向下一个数字字符加个位数是负数则求补存结果结束NYYN转换子程序转换子程序程序如下:DATASEGMENTSTR1DB 10,?,10 DUP(?) ;第1个数的输入缓冲区STR2DB 10,?,10 DUP(?) ;第2个数的输入缓冲区NUMDW ?,? ;存转换后的二进制数SUMDW 0 ;存和OVERDB Overflow!,13,10,$DATAENDS
151、;CODESEGMENTASSUME CS:CODE,DS:DATAMAINPROCFARSTART: MOVAX,DATAMOVDS,AXMOVAH,0AHLEADX,STR1STR1INT21H ;输入第一个数字串(设为26)MOVAH,0AHLEADX,STR2STR2INT21H ;输入第二个数字串(设为33)LEABX,STR1 ;串1的首地址送BXLEADI,NUM ;存二进制首地址送DI CALLCHANGE ;将串1 ASCII码二进制 LEABX,STR2 ;串2的首地址送BX LEADI,NUM+2;指向CALLCHANGE;将串2 ASCII码二进制MOVAX,NUM ;
152、(AX)=NUM=001AH ADDAX,NUM+2;两数相加,(AX)=003BHMOVSUM,AX;存和JNONEXT;无溢出,转NEXTLEADX,OVERMOVAH,9INT21H;显示Overflow!NEXT:MOVAH,4CHINT21H;返回DOS MAINENDPCHANGEPROCMOVCL,BX+1;实际字符数送CLMOVAL,BX+2;第一个字符送ALMOVCH,AL;暂存在CHCMPAL,-;第一个字符是负号吗?JNZNEXT1;不是,转NEXT1DECCL;字符数减1INCBXNEXT1: ADDBX,2;指向第一个数字字符MOVAX,0;清零AX,存二进制数LP1
153、: DECCLJZNEXT2;若(CL)=0,转NEXT2MOVDL,BX ;取字符ANDDL,0FH;转换成BCD码 ADD AL,DL ;加到中间结果上 ADC AH,0 MOV DX,10 MUL DX ;*10 INC BX ;指向下一个字符 JMP SHORT LP1NEXT2: MOV DL,BX ;取个位数 AND DL,0FH ;个位ASCII未组合BCD ADD AX,DX ;加个位数,(AX)=001AH CMP CH,- ;是-? JNZ NEXT3 ;该数非负,转NEXT3 NEG AX ;若为负,求补NEXT3: MOV DI,AX ;存二进制结果 RETCHANGE
154、 ENDP;CODE ENDS END START020A32360D020A33330D001A21003B00STR1STR2NUMSUM10个10个OOVER?040A313234STR1若键入 1234330D1 2 3 4设键入第设键入第1 1个数为个数为26, 26, 第第2 2个数为个数为33,33,则在内存各变量分配如下则在内存各变量分配如下: :本例题重点掌握:如何从键盘输入一个字符串ASCII未组合BCD二进制有符号数的运算,对负数和溢出如何处理思考题: 若键入第一个数26,第二个数为-4,填写各变量结果。方法1 计算二进制数中所包含的1000的个数、100的个数、10的个
155、数和1的个数。方法2 除10取余。下面举例介绍第一种方法。流程图如下:二进制数BCDYN二进制数二进制数AX令(令(DL)0(AX)-10000?(DL)+1(AX)+1000(AX)DL存至缓冲区存至缓冲区令令(DL)0YN(AX)-100?(DL)+1(AX)+10(AX)存存DL存存AL返回返回DOS求100的个数,结构同上A汇编程序如下:DATASEGMENTBNUMDB270FHDNUMDB4 DUP(?) ;存放BCD码的缓冲区DATAENDSCODESEGMENTASSUME CS:CODE,DS:DATABINBCDPROCFARBEGIN: MOVAX,DATAMOVDS,A
156、XMOVAX,BNUM ;取二进制数LEABX,DNUM ;BCD码缓冲区首地址送BX ;计算百位的个数 MOV DL,0 ;千位的个数计数器AGAIN1: SUB AX,1000 ;(AX)-1000 JC NEXT1 ;若0,则退出循环 INC DL ;(DL)+1 JMP AGAIN1NEXT1: ADD AX,1000 ;(AX)(AX)+1000 MOV BX,DL ;存千位的个数 ;计算百位的个数 MOV DL,0 ;百位的个数计数器AGAIN2: SUB AX,100 ;(AX)-100 JC NEXT2 INC DL JMP AGAIN2NEXT2: ADD AX,100 MO
157、V BX+1,DL ;存百位的个数 MOV DL,0 ;十位的个数计数器AGAIN3: SUB AX,10 ;(AX)-10 JC NEXT3 INC DL JMP AGAIN3NEXT3: ADD AX,10 MOV BX+2,DL ;存十位的个数 MOV BX+3,AL ;存个位的个数 MOV AH,4CH INT 21HBINBCD ENDP;CODE ENDS END BEGINBCDASCII 前面举例介绍过,略。二进制串转换为ASCII码 一个二进制位串若要送显示或打印, 需把串中每一位(0或1)化为ASCII码。 思路:先将目标串全部预置为30H,再把每个二进制位逐位左移至CF,
158、然后判CF=0?若是,取下一位;若不是,将31H送此单元。 流程图如下:初始化用0填满串取要转换的数左移1位存入1结束CF=1?转换完?调整指针NN汇编程序如下:DATASEGMENTNUMDW6F78HSTRINGDB16 DUP(?)DATAENDS;CODESEGMENTASSUME CS:CODE,DS:DATABINCAPROCFARBEGIN:MOVAX,DATAMOVDS,AXMOVES,AXCLDLEADI,STRINGMOVCX,16 ;串的长度MOVAL,30HREPSTOSB ;串中全部填充为0MOVCX,16LEADI,STRINGMOVAL,1MOVBX,NUM ;(
159、BX)=6F78HAGAIN: RCLBX,1 ;含进位位循环左移JNCNEXT ;若为0,转 MOV DI,AL ;若为1,对应位送入1NEXT:INCDILOOP AGAINMOVAH,4CHINT21HBINCAENDPCODEENDSENDBEGIN 编写子程序时,很重要的一个工作是如何把参数传给子程序,这个过程叫参数传送。 传送方法有:l把参数放在CPU内部寄存器中l把参数放在变量中l把参数放在地址表中l利用堆栈传送参数 下面举例介绍第4种方法,它通常在主程序中把参数或参数地址保存在堆栈中,而在子程序中将参数从堆栈取出来。例:把一个用十六进制表示的字ASCII码,然 后送到屏幕上显示
160、。 汇编程序如下:DATASEGMENTNUMDW25AFH ;要显示的数STRINGDB4 DUP(?),13,10,$DATAENDSSTACKSEGMENTDB 100 DUP(?)TOP EQU $ STACKENDS ; CODESEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVES,AXMOVAX,STACKMOVSS,AX MOV SP,TOP LEABX,STRING;取变量偏址PUSHBX;将偏址压栈PUSHNUM;将变量压栈00020064H0062H(SP)25AF0060H堆
161、栈 CALLCALLBINHEXBINHEX;(SP)=005EH CS:0113CS:0113 LEADX,STRING;(DX)=0002HMOVAH,9INT21HMOVAH,4CHINT21H;*BINHEXPROCPUSHBP;(SP)=005CHMOVBP,SP ;(BP)=005CHPUSHAX ;(SP)=005AHPUSHDI ;(SP)=0058HPUSHCX ;(SP)=0056HPUSHDX ;(SP)=0054H00020064H0062H25AF0060H005EH0113005CH(SP)返回地址(IP)原(BP)00020064H0062H25AF0060H00
162、5EH0113xxxx005CH(BP) PUSHF ;(SP)=0052H MOV AX,BP+4 ;(AX)=25AFH MOV DI,BP+6 ;(DI)=0002H ADD DI,LENGTH STRING-4;(DI)=0005H MOV DX,AX ;(DX)=25AFH MOV CX,4 STD ;从后往前存AGAIN:AND AX,0FH ;第一次(AX)=000FH CALL HEXDCALL HEXD ;转换为ASCII码 STOSB PUSH CX MOV CL,4 SHR DX,CL ;逻辑右移4位 MOV AX,DX ;第1次(AX)=025AH POP CX LOO
163、P AGAIN ;(CX)-1=0?不等,转+4POPFPOPDX POPCXPOPDIPOPAXPOPBPRET4 BINHEX ENDP ;*HEXD PROC CMP AL,0AH JL LP ADD AL,7LP: ADD AL,30H RETHEXD ENDPCODE ENDS END BEGIN0064H0062H0060H005EH005CH000225AF0113xxxx(SP) 从本例可知,通过堆栈传递的两个参数分别为:变量NUM的内容25AFH和变量STRING的偏移地址。这两个参数在调用子程序之前压入堆栈,当CALL指令返回时,其(SP)=0060H,不是初值0064H。故采用带参数返回指令RET 4。 本例重点掌握: 进一步了解堆栈的使用 学会RET n的应用 子程序嵌套