第6章汇编语言程.ppt

上传人:本田雅阁 文档编号:3503104 上传时间:2019-09-04 格式:PPT 页数:47 大小:293.05KB
返回 下载 相关 举报
第6章汇编语言程.ppt_第1页
第1页 / 共47页
第6章汇编语言程.ppt_第2页
第2页 / 共47页
第6章汇编语言程.ppt_第3页
第3页 / 共47页
第6章汇编语言程.ppt_第4页
第4页 / 共47页
第6章汇编语言程.ppt_第5页
第5页 / 共47页
点击查看更多>>
资源描述

《第6章汇编语言程.ppt》由会员分享,可在线阅读,更多相关《第6章汇编语言程.ppt(47页珍藏版)》请在三一文库上搜索。

1、2019/9/4,1,第6章 汇编语言程序设计,汇编语言是面向机器、功能很强的程序设计语言,也是利用计算机所有硬件特性并能直接控制硬件的语言。 使用汇编语言编写的程序,需要被翻译成机器语言,才能被计算机识别,这种起翻译作用的程序叫汇编程序。 汇编语言编译器把汇编语言源程序翻译成机器语言的过程称为汇编。高级的汇编器(如MASM、TASM)为程序员编写汇编程序提供了很多类似于高级语言的特征,比如结构化、抽象等。 在这样的环境中编写的汇编程序,有很大一部分是面向汇编器的伪指令,已经类同于高级语言。,2019/9/4,2,指令:是可执行的,汇编后由相应的机器代码所取代; 伪指令:是不可执行的,只是在源

2、程序汇编期间由汇编程序处理的命令,指示汇编程序为数据分配内存空间,或者提供段定义等信息,不产生任何机器代码,2019/9/4,3,6.1 汇编语言程序概述,STACK_SEG SEGMENT STACK ;定义堆栈段STACK_SEG DW 100H DUP(?) ;分配堆栈段大小为512字节 STACK_SEG ENDS ;堆栈段结束 DATA_SEG SEGMENT ;定义数据段DATA_SEG X DB 10 ;定义数据 Y DB 5 Z DB 1 ANS DB ? DATA_SEG ENDS ;数据段结束 CODE_SEG SEGMENT ;定义代码段CODE_SEG ASSUME C

3、S:CODE_SEG,DS:DATA_SEG ;确定CS/DS/SS指向的逻辑段 START: MOV AX,DATA_SEG ;装入数据段的段地址DS MOV DS, AX MOV AL,X ;程序代码 ADD AL,Y SUB AL,Z MOV ANS,AL MOV AX,4C00H ;返回DOS INT 21H CODE_SEG ENDS ;代码段结束 END START ;汇编结束,程序起始点为START,2019/9/4,4,.MODEL SMALL .STACK 100H .DATA S1 DB 100 DUP(5) S2 DB 100 DUP(?) .CODE .STARTUP

4、Mov ax, ds Mov es, ax Mov cx, 50 CLD MOV SI, OFFSET S1 MOV DI, OFFSET S2 REP MOVSB Mov ah ,9 Mov dx, offset s2 Int 21h .EXIT 0 END,2019/9/4,5,6.1.1 汇编语言程序的语句格式,一、执行性语句 执行性语句是由可执行指令构成的语句,即为指令系统中的指令, 以机器码的形式保存在程序的代码段中。其语句的完整格式为: 标号:指令助记符 操作数,操作数;注释 标号是用户定义的标识符,它反映了指令的位置(逻辑地址)和类型。标号后跟一个冒号分隔,通常表示转移指令或循环

5、指令的目标地址。例如JMP LABL,即为跳转到LABL标号处的指令执行。标号为可选项。 标示符的命名有一定的规则: 一般最多由31个字母、数字及规定的特殊符号(如_、$、?、)组成, 不能以数字开头; 不能用系统的保留字; 标识符定义不区分大小写字母,且每一个标识符都是唯一的。,2019/9/4,6,二、说明性语句 说明性语句是由伪指令构成的语句,它通常指示汇编程序如何汇编源程序。其语句完整格式为: 名字 伪指令助记符 参数,参数,. ;注释 1、名字是用户定义的标识符,其命名规则与标号相同。名字通常用于定义变量名、过程名或者段名。名字和伪指令助记符之间用空格或制表符分隔。 2、伪指令助记符

6、 伪指令不产生CPU动作,是在程序执行前由汇编程序处理的说明性指令。例如X DB 10;DB即为定义变量X的伪指令。 3、参数 伪指令的参数可以是常数、变量名、表达式等,可以有多个,参数之间用逗号分隔。,2019/9/4,7,6.1.2 汇编语言的程序格式,简化段定义格式简洁、易于掌握,引入存储模式使得程序方便地与其他微软开发工具组合; 完整段定义格式烦琐,但可以提供更多的段属性,有时也是必须采用的; 只有MASM5.0以后的版本才支持简化段定义。,2019/9/4,8,-完整段定义格式: STACK_SEG SEGMENT STACK ;定义堆栈段STACK_SEG DW 100H DUP(

7、?) ;分配堆栈段大小为512字节 STACK_SEG ENDS ;堆栈段结束 DATA_SEG SEGMENT ;定义数据段DATA_SEG S1 DB 100 DUP(5) S2 DB 100 DUP(?) DATA_SEG ENDS ;数据段结束 CODE_SEG SEGMENT ;定义代码段CODE_SEG ASSUME CS:CODE_SEG,DS:DATA_SEG,ES:DATA_SEG START: MOV AX,DATA_SEG ;设置数据段的段地址DS MOV DS,AX CLD ;程序代码 MOV SI,OFFSET S1 MOV DI,OFFSET S2 REP MOVS

8、B MOV AX,4C00H ;返回DOS INT 21H CODE_SEG ENDS ;代码段结束 END START ;汇编结束,程序起始点为START,2019/9/4,9,-简化段定义格式完成例6.1。 .MODEL SMALL ;定义程序的存储模式(一般采用small) .STACK ;定义堆栈段 .DATA ;定义数据段 X DB 10 ;定义数据 Y DB 5 Z DB 1 ANS DB ? .CODE ;定义代码段 .STARTUP ;程序起始点,并建立DS、SS内容 MOV AL,X ;程序代码 ADD AL,Y SUB AL,Z MOV ANS,AL .EXIT0 ;程序结

9、束点,返回DOS END ;汇编结束,2019/9/4,10,6.1.3 伪指令,一、变量定义伪指令 变量的实质就是指向内存中某个地址的指针,例如定义了一个变量VAR1,指向1000:1234内存单元。当需要访问该单元的数据时,直接引用变量名就可以。变量的命名需符合标识符命名规则。 变量定义伪指令就是为变量指定名称和类型,并为变量分配存储单元,有时还直接对内存单元进行初始化,即赋值。,2019/9/4,11,DB定义字节,用于分配一个或多个字节单元。 DW定义字,用于分配一个或多个字单元,每个字的低位字节存储在低地址,高位字节存储在高地址。 DD定义双字,用于分配一个或多个双字单元,每个双字的

10、低位字存储在低地址,高位字存储在高地址。 DF/DQ/DT 定义三字/四字/十字节。 1、数值表达式 【例6.5】 ORG 100H ;从偏移地址100H处开始安排数据或程序 VAR1 DB 01H, -1 VAR2 DW 1234H, 78H,2019/9/4,12,2、?表达式 ANS DB ? 汇编程序仍然为其分配存储单元,但不预留确定的值。预留的单元常用来存放程序的中间结果和最终结果。 3、带DUP的表达式 VAR1 DB 5 DUP(0) ;等价于VAR1 DB 0,0,0,0,0 DW 2 DUP(?) ;变量名缺省,等价于DW ?,? VAR2 DB 2 DUP(3 DUP(3)

11、,2) ;DUP的嵌套使用 ;利用带DUP的表达式可以为若干重复数据分配存储单元。 4、字符串 当运用DB命令定义字符串时,将为串中的每个字符分配一个字节存储单元。字符串要用引号括起,单双引号均可,且不能超过255个字符。按照字符串从左到右的顺序,内存单元中由低到高依次保存的为字符的ASCII码。 ORG 1000H DATA1 DB A ;等价于DATA1 DB 41H DATA2 DB 123456 ;等价于DATA2 DB 31H,32H,33H,34H,35H,36H,2019/9/4,13,5、标号或变量 ORG 1000H ANS DB ? X1 DW ANS X2 DD LABL

12、 LABL: MOV AX,3 ;假设该指令的地址为0200H:1200H 当使用DW时,则将DW后的变量ANS的偏移地址值1000H保存至X1指向的内存单元。 当使用DD时,则将DD后的标号LABL的段地址0200H和偏移地址1200H分别保存至X2指向的内存中的高地址和低地址单元。,2019/9/4,14,ORG 200H D_BYTE DB 30H,40H DB 50H D_WORD DW 1234H,5678H D_DWORD DW D_WORD D_TBYTE DT ? D_FWORD DF 1234567890ABH D_QWORD DQ 1122334455667788H,当前位

13、置计数器 汇编时将段名填入段表,同时为该段配备一个初值为0的位置计数器$。计数器依次累计段内语句被汇编后生成的目标代码字节个数。可用ORG伪指令把位置计数器的值设置成需要的值。 例: ORG 0F0H ;从0F0H开始安排数据 ORG $+10H ;跳过10H个字节后安排数据 DW 1,$+4,$+4 ;100H单元的字值为1,102H单元的字值 ;为106H,104H单元的字值为108H ARRAY DB 12,34,56,5 DUP (?) ;定义字节数组 LEN EQU $-ARRAY ;LEN的值为ARRAY变量所占的字节数8,2019/9/4,15,二、常量定义伪指令,常量就是利用一

14、个标识符表达的一个数值。运用符号名来表示常数,可以提高程序的可读性和通用性。常量定义与变量定义的区别在于,常量定义不分配内存单元。 常量定义伪指令有等价EQU和等号=,其语句格式如下: 常量名 EQU 常量名 = 区别:使用等号=伪指令,可以对同一个常量重复定义,后一条覆盖前一条;而EQU则禁止重复定义。 TEN EQU 10 MOV AX,TEN 等价于 MOV AX,10 EQU 还可以用表达式的值为常量赋值,表达式由各种操作符构成。,2019/9/4,16,三、表达式操作符,1、算术操作符 算术操作符包括+(加)、-(减)、*(乘)、/(除)、MOD(模除)、SHL(左移)、SHR(右移

15、)共7种。 参加运算的数和运算结果都为整数。 由这些算术操作符构成算术表达式,表达式中的运算在汇编时完成。 只有加、减运算可以使用变量和标号参与运算,表示同一段中偏移地址的增、减。 K EQU 5+3 ;等价于K EQU 8 S1 DB 1,3,5,7,9 MOV AL, S1+3 ;AL=7 MOV AL, 11B SHL 5 ;(AL)=01100000B,2019/9/4,17,2、逻辑操作符 逻辑操作符包括AND(与)、OR(或)、XOR(异或)、NOT(非)共4种。运算是按位进行的,且只适用于常量的逻辑运算。 K EQU 0F0H AND 0FH ;等价于K EQU 00H MOV

16、AL, NOT K ;AL=0FFH 3、关系操作符 关系操作符包括EQ(相等)、NE(不等)、LT(小于)、LE(小于等于)、GT(大于)、GE(大于等于)共6种。 运算返回的结果只有两种:若关系成立,则为全1(真);反之为全0(假)。 MOV AX, 5 EQ 6 ;AX=0FFFFH MOV BX, 5 LT 6 ;BX=0000H,2019/9/4,18,4、数值返回操作符 数值返回操作符包括OFFSET(返回偏移地址)、SEG(返回段地址)、TYPE(返回类型属性)、 LENGTH(返回个数)、SIZE(返回字节数)共5种。 数值返回操作符后只跟一个操作对象,这个操作对象只能是变量或

17、标号。返回结果以数值的形式表示。,【例6.14】已知DS=1000H,定义了两个变量VAR1、VAR2 请参考图6.1 MOV DI,OFFSET VAR1 ;取偏移地址,DI=0100H MOV AX,SEG VAR1 ;取段地址,AX=1000H MOV BL,TYPE VAR2 ;VAR2的类型属性为字,BL=2 变量的类型可以为字节、字、双字等等,用数值表示即为其字节的个数,2019/9/4,19,LENGTH:若是用DUP定义的变量,则LENGTH返回DUP前面的数值n;其他情况返回值为1。 SIZE返回的结果是TYPELENGTH。若是用DUP重复定义的变量,则SIZE返回的数值为

18、该变量所占的总字节数。 【例6.15】 S1 DB 5 DUP (0) S2 DW 100 DUP(?) S3 DB 1,2,3,4,5 MOV AL,SIZE S1 ;AL=15=5 MOV BL,SIZE S2 ;BL=2100=200 MOV CL,SIZE S3 ;CL=11=1,2019/9/4,20,LENGTHOF运算符,该运算符加在变量名之前,返回的数值是变量中所定义的元素个数。 D1 DW 10H DUP (0),1234H D2 DB 20H DUP (2 DUP(0),1) D3 DQ 1234H, 5678H D4 DB ABCDEFGH D5 DD 12H,34H,

19、;加一个续行符,表示一条伪指令占两行 56H,78H D6 DD 12H,34H ;未加续行符,则表示这两行是两条伪指令 DD 56H,78H MOV AL,LENGTHOF D1 ;(AL)= 11H MOV AL,LENGTHOF D2 ;(AL)= 60H MOV AL,LENGTHOF D3 ;(AL)= 2H MOV AL,LENGTHOF D4 ;(AL)= 8H MOV AL,LENGTHOF D5 ;(AL)= 4H MOV AL,LENGTHOF D6 ;(AL)= 2H,2019/9/4,21,SIZEOF运算符,该运算符加在变量名之前,返回的数值是变量所占的总字节数,且等

20、于LENGTHOF和TYPE两个运算符返回值的乘积。例如,对于上例中的变量,SIZEOF的返回值如下所示: MOV AL,SIZEOF D1 ;(AL)= 22H,即20H*2H MOV AL,SIZEOF D2 ;(AL)= 60H,即60H*1H MOV AL,SIZEOF D3 ;(AL)= 10H,即8H*2H MOV AL,SIZEOF D4 ;(AL)= 8H,即8H*1H MOV AL,SIZEOF D5 ;(AL)= 10H,即4H*4H MOV AL,SIZEOF D6 ;(AL)= 8H,即2H*4H,2019/9/4,22,5、属性操作符,(1)PTR PTR为类型操作符

21、,其功能是对变量或标号的类型属性进行有关设置。指定的属性可以为BYTE(字节)、WORD(字)、DWORD(双字)、FWORD(三字)、QWORD(四字)、TBYTE(10字节),或者是NEAR(近)、FAR(远)。PTR使用格式为: PTR VAR1 DB 1, 2 VAR2 EQU WORD PTR VAR1 MOV AL, VAR1 ;AL=01H MOV AX, WORD PTR VAR1 ;AX=0201H MOV AX, VAR2 ;AX=0201H,2019/9/4,23,(2)THIS EQU THIS连用,是将其后的属性赋给当前的变量或标号。 VAR1 EQU THIS BY

22、TE VAR2 DW 5678H VAR1和VAR2具有相同的地址,属性不同。 (3)LABEL LABEL等价于EQU THIS。 VAR1 LABEL BYTE VAR2 DW 5678H VAR1和VAR2具有相同的地址,属性不同。 (4)HIGH/LOW MOV AH, HIGH 1234H ;AH=12H MOV AL, LOW 1234H ;AL=34H HIGH和LOW分别用于从16位操作数中分离出高字节和低字节。,2019/9/4,24,运算符的优先级,一般可以用括号来改变运算符的优先级别。 例: MOV AL,18 OR 5 AND 10 ;AL=18(12H) MOV AL

23、,(18 OR 5) AND 10 ;AL=2,2019/9/4,25,四、段定义伪指令,1、完整段定义伪指令 (1) SEGMENT ENDS SEGMENT伪指令定义一个逻辑段的开始,ENDS伪指令表示一个段的结束。这两条语句可以完成一个段的定义。 STACK_SEG SEGMENT STACK ;定义堆栈段STACK_SEG DW 100H DUP(?) ;分配堆栈段的大小512字节 STACK_SEG ENDS ;堆栈段结束 段定义的完整格式如下: SEGMENT 定位,组合,段字,类别 ;语句序列 ENDS SEGMENT后的4个关键字,用于确定段的各种属性,堆栈段要采用stack组

24、合类型,其他为可选属性参数。如果不指定,则采用默认参数。但如果指定,注意要按照上列次序。,2019/9/4,26,(2)ASSUME 格式:ASSUME 段寄存器:段名 ,段寄存器名:段名, ASSUME伪指令的功能是建立段寄存器与逻辑段的默认关系,明确程序中各段与段寄存器之间的关系。 ASSUME伪指令并不为段寄存器设定初值,所以在源程序中,用户首先必须为DS、 ES赋值。 连接程序LINK将自动设置CS : IP和SS : SP。 ASSUME CS:CODE,DS:DATA ;确定CS/DS/SS指向的逻辑段 MOV AX, DATA ;装入数据段的段地址DS MOV DS, AX,20

25、19/9/4,27,2、简化段定义伪指令,(1).MODEL .MODEL SMALL ;定义程序的存储模式为SMALL TINY:微型模式,程序中的数据和代码放在同一64K段内,这也就是后缀为.COM的程序。这种模式是MASM6才引入的。 SMALL:小型模式,程序中的代码放在64KB的数据段内, 数据放在64KB代码的段内(包括数据段、堆栈段和附加段公用一个段),因而对代码和数据的访问可通过近程(NEAR)调用来实现。一般程序默认的都是该模式。 MEDIUM:中型模式,程序中的数据放在64KB的数据段内,代码量大于64KB,因而可安排在不同段内。这样,数据是近程的,而代码是远程的。 COM

26、PACT:压缩模式,程序中的所有代码放在一个64KB的代码段内,而数据区可以大于64KB。这样,对代码的访问是近程的,而数据是远程的。 LARGE:大型模式,程序中的数据和代码均大于64KB,但静态(常数)数据限制在64KB之内。对程序和数据的访问默认都是远程的。 HUGE:巨型模式,程序中的数据和代码均大于64KB,静态数据也可以大于64KB。这样,对代码、数据和数组的访问都是远程的。 FLAT:平展模式,用于创建一个32位的程序,它只能运行在32位80X86CPU上。DOS下不能使用FLAT模式,而编写32位Windows程序时,必须采用FLAT模式。 (2)定义堆栈段.STACK 大小

27、堆栈段伪指令.STACK创建一个堆栈段,默认段名为stack。可选大小参数用于指定堆栈段所占存储区的字节数,缺省则默认为1KB。,2019/9/4,28,处理器选择伪指令 .8086和.8087 可用来汇编8086/8088处理器和8087协处理器的指令,这是缺省模式。 .286、.286C、.286P、.287可用来汇编286系列微处理器的指令。 .386、.386C、.386P、.387可用来汇编386系列微处理器的指令。 .NO87取消使用协处理器指令。 .486、.486C、.486P可用来汇编486系列微处理器的指令。 .586、.586C、.586P可用来汇编Pentium系列微处

28、理器的指令。 . 686、.686P可用来汇编Pentium Pro系列微处理器的指令。 .MMX可用来汇编MMX指令。 .MMX和.686、.686P是MASM6.12引入的。 .K3D 可用来汇编AMD处理器的3D指令,是MASM6.13引入的。 .XMM可用来汇编SSE指令和SSE2指令,是MASM6.15引入的。 注意:80386以上处理器中,如果处理器选择伪指令放在.MODEL伪指令前面,那么段将定义成32位的段。如果希望处理器使用16位的段,则应在.MODEL伪指令后面使用处理器选择伪指令。,2019/9/4,29,(3)定义数据段.DATA 伪指令.DATA创建一个数据段,默认段

29、名为_DATA。该伪指令后可进行常量或变量的定义。 .DATA S1 DB 100 DUP(5) S2 DB 100 DUP(?) (4) 定义代码段.CODE 段名 伪指令.CODE创建一个代码段,其后可选段名参数用于指定该代码段的段名,缺省则默认为_TEXT。 (5).STARTUP 该伪指令按照给定的CPU类型、存储模式以及操作系统和堆栈类型,产生程序开始执行的代码; 还指定了程序开始执行的起始点; 还完成一些初始化工作,如赋值DS,调整SS和SP值。,2019/9/4,30,(6).EXIT .EXIT功能为终止程序,返回操作系统。后跟返回参数,通常用0表示没有错误,相当于完整段定义中

30、的: MOV AX, 4C00H INT 21H 这是利用了功能号为4CH的DOS功能调用,实现程序的返回。入口参数AL = 0,表示正确返回。 .STARTUP和.EXIT伪指令是MASM 6.0才引入的。 (7)END 标号 END伪指令表示汇编结束。源程序的最后必须有一条END语句。后跟可选的标号,用于指定程序开始执行点。 段序定义伪指令 MASM可以按照源程序中各个段出现的次序来排列目标文件中各段的先后次序,也可以按照段名的字母顺序来排列次序。缺省情况是按照段出现的次序来排列,可以定义段序: .ALHPA:按照字母顺序对段排序。 .SEG:按照段出现的顺序对段排序。完整段定义格式中,默

31、认按此顺序。 .DOSSEG:按照DOS定义的标准段序对段排序,顺序为:代码段、数据段、堆栈段。采用.MODEL伪指令的简化段定义格式默认按此顺序。,2019/9/4,31,五、过程定义伪指令,过程也称为子程序,过程的定义由一对过程伪指令PROC和ENDP来完成。格式如下: 子程序名 PROC NEAR/FAR ;子程序指令 RET 子程序名 ENDP 使用子程序时需要注意以下三方面: 1、子程序定义的位置应在返回DOS后,汇编结束前。 ;主程序指令 MOV AX,4C00H ;返回DOS INT 21H 子程序定义 END START ;汇编结束 2、子程序的调用与返回是由指令CALL和RE

32、T来完成的,故子程序定义结束前,必须有RET。 3、主程序中调用子程序时,必须注意寄存器的保护与恢复。在使用堆栈操作时,要注意前文提到的先进后出原则,注意PUSH和POP指令的成对使用。,2019/9/4,32,六、其它伪指令,前面已经叙述过! 1、ORG ORG伪指令是将ORG后跟的参数作为其后指令的起始偏移地址。 ORG 100H ;表示从偏移地址为100H处,开始安排数据或程序 ORG $+10 ;使偏移地址加10,即跳过10个字节空间 2、$ 汇编语言程序中,符号“$”表示当前偏移地址值。 ORG 0100H DW 1,2,$+4,$+4 VAR1 DB 12,23,34 LEN EQ

33、U $-VAR1 -104H=0108H、106H=10AH、LEN=3。,2019/9/4,33,6.2 汇编语言程序的上机过程,6.2.1 建立汇编语言的开发环境 MASM和TASM分别为微软公司和Borland公司所开发的汇编程序。 6.2.2 汇编语言程序的开发过程 一、源程序的编辑 汇编语言源程序扩展名为.ASM。源程序编辑可以通过文本编辑器实现: 在DOS下,运行全屏幕文本编辑器EDIT。 C:EDIT 6_1.ASM。 二、源程序的汇编 汇编是将源程序翻译成由机器码组成的目标文件的过程。例如: C:MASM5.0MASM 6_1.ASM 如果源程序中没有语法错误,MASM将自动生

34、成一个目标模块文件6_1.OBJ。在汇编过程中还可以选择生成列表文件,扩展名为.LST,该文件将列出源程序和对应的机器语言清单。例如6_1.LST文件。,2019/9/4,34,LINE LOC: MACHINE CODE SOURCE 1 : DATA SEGMENT 2 0000: 0A X DB 10 3 0001: 05 Y DB 5 4 0002: 01 Z DB 1 5 0003: 00 ANS DB ? 6 : DATA ENDS 7 : 8 : CODE SEGMENT 9 : ASSUME CS:CODE,DS:DATA 10 0010: B8 00 00 START: MO

35、V AX,DATA 11 0013: 8E D8 MOV DS,AX 12 : 13 0015: A0 00 00 MOV AL, X 14 0018: 8A 1E 01 00 MOV BL, Y 15 001C: 02 D8 ADD BL, AL 16 001E: 2A 1E 02 00 SUB BL, Z 17 0022: 88 1E 03 00 MOV ANS,BL 18 : 19 0026: B8 00 4C MOV AX,4C00H 20 0029: CD 21 INT 21H 21 : 22 : CODE ENDS 23 : END START,2019/9/4,35,三、目标模块

36、的连接 连接程序能把一个或多个目标文件和库文件合成一个可执行程序(.EXE、.COM文件),例如: C:MASM5.0LINK 6_1.OBJ 如果没有严重错误,LINK将生成一个可执行文件6_1.EXE;否则将提示相应的错误信息。 四、可执行程序的调试 经汇编、连接生成的可执行程序在操作系统下只要输入文件名就可以运行: C:MASM5.06_1.EXE 如果出现运行错误,可以从源程序开始排错,也可以利用调试程序帮助发现错误。如采用DEBUG.EXE调试程序,则执行下条命令: C:MASM5.0DEBUG 6_1.EXE 程序的调试,可以借助汇编集成开发环境EMU8086进行,利用其“sing

37、le step”单步执行,仔细观察程序执行过程中,CPU内部各个寄存器、内存单元和标志寄存器的变化。EMU8086自带的帮助文件,对于汇编语言的初学者也非常有帮助。,2019/9/4,36,【例6.23】计算X+Y-Z,并将结果以二进制数形式输出。 DATA SEGMENT ;定义数据段 X DB 10 Y DB 5 Z DB 1 ANS DB ? DATA ENDS CODE SEGMENT ;定义代码段 ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AL,X ;计算X+Y-Z ADD AL,Y SUB AL,Z MOV AN

38、S,AL MOV CX,8 PRINT: MOV AH,2 ;按位从左到右输出结果,DOS功能调用 MOV DL,1 TEST ANS,10000000B JNZ ONE MOV DL,0 ONE: INT 21H SHL ANS,1 LOOP PRINT MOV DL,B ;输出二进制位b INT 21H MOV AX,4C00H ;返回DOS INT 21H CODE ENDS END START ;汇编结束,2019/9/4,37,【例6.24】将数组VEC1和VEC2中的元素逐个相加,结果保存在数组VEC3。 .model small .386 .stack .data VEC1 DB

39、 1, 2, 5, 6 VEC2 DB 3, 5, 6, 1 VEC3 DB ?, ?, ?, ? .code .startup LEA SI,VEC1 ;地址指针 LEA BX,VEC2 LEA DI,VEC3 MOV CX,4 SUM: MOV AL,SI ADD AL,BX ;VEC1+VEC2 MOV DI,AL ;结果保存在VEC3 INC SI ;指针加1,指向下一个元素 INC BX INC DI LOOP SUM .exit 0 END ;汇编结束,2019/9/4,38,【例6.26】比较字符串是否相同,相同输出Y,不同输出N。 .model small .386 .stac

40、k .data STR1 DB test string STR2 DB test streng LEN=($-STR1)/2 .code .startup MOV AX , DS MOV ES,AX CLD ;程序代码 MOV SI,OFFSET STR1 MOV DI, OFFSET STR2 MOV CX, LEN REPE CMPSB ;ZF=0且CX0,重复比较 JNZ NO_MATCH ;判断停止重复的原因 MOV DL,Y ;DOS功能调用输出字符 MOV AH,02H INT 21H JMP EXIT_HERE NO_MATCH: MOV DL,N MOV AH,02H INT

41、21H EXIT_HERE: .exit 0 END ;汇编结束,2019/9/4,39,【例6.27】调用DISP过程,在显示器屏幕上显示“OK”。 DATA SEGMENT ;定义数据段 STRING DB OK,0DH,0AH,$ DATA ENDS CODE SEGMENT ;定义代码段 ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV DX,OFFSET STRING CALL DISP MOV AX,4C00H ;返回DOS INT 21H DISP PROC NEAR ;定义过程DISP PUSH AX ;入栈保护寄存

42、器 MOV AH,09H ;选择功能号02H INT 21H ;执行DOS功能调用 POP AX ;出栈恢复寄存器 RET ;从过程返回 DISP ENDP CODE ENDS END START ;汇编结束,2019/9/4,40,6.3 系统功能调用,6.3.1 概述 DOS系统功能调用提供了近百个功能供用户选择使用,是一个功能齐全、使用方便的中断服务程序集合。 ROM-BIOS也以中断服务程序的形式向程序员提供系统的基本输入输出程序,它的功能更加强大。程序员在进行汇编语言程序设计时可利用系统提供的这些资源,也就是直接调用系统提供的具有各种功能的子程序,这是程序设计的一个重要方面。 所有系

43、统功能调用的格式都是一样的,一般按如下四步进行: 1、在AH寄存器中设置子功能号; 2、在指定的寄存器中设置入口参数; 3、用相应的中断指令执行功能调用; 4、根据出口参数分析功能调用的执行情况。,2019/9/4,41,6.3.2 DOS系统功能调用INT 21H,一、一个字符的输出 子功能号:AH=02H。 入口参数:DL=输出字符的ASCII码。 执行该功能后会在显示器当前光标处显示指定的字符,且光标右移一个字符位置。 【例6.29】用02H号DOS系统功能调用在显示器输出一个字符。 MOV AH,02H ;设置子功能号,AH=02H MOV DL,K ;设置入口参数,DL=K(DL为字

44、符的ASCII码) INT 21H ;DOS功能调用,显示该字符 在进行字符输出时,当输出响铃字符(ASCII码为07H)、退格字符(08H)、回车字符(0DH)、换行字符(0AH)时,能自动识别并能进行相应处理。 二、一个字符串的输出 子功能号:AH=09H。 入口参数:DS:DX=待显示字符串在内存中的首地址。字符串应以$(24H)结束,可以输出回车和换行字符产生回车和换行的作用。 【例6.30】用09H号DOS系统功能调用在显示器输出一个字符串。 STRING DB Hello,World!,0DH,0AH,$ ;定义要显示的字符串 MOV AH,09H ;设置子功能号,AH=09H M

45、OV DX,OFFSET STRING ;设置入口参数,DX字符串偏移地址 INT 21H ;DOS功能调用,显示字符串,2019/9/4,42,三、一个字符的输入 子功能号:AH=01H。 出口参数:AL输入字符的ASCII码。调用此子功能时,若无键按下,则会一直等待,直到有键按下时读取该键值。输入字符时有回显功能。 【例6.31】判断按键是Y还是N。 MOV AH,01H ;设置子功能号,AH=01H INT 21H ;有按键时AL按键的ASCII码 CMP AL,Y JZ KEYYES ;是Y转移到KEYYES执行 CMP AL,N JZ KEYNO ;是N转移到KEYNO执行 四、一个

46、字符串的输入 子功能号:AH=0AH。 入口参数:DS:DX缓冲区首地址。缓冲区第一字节为缓冲区大小,事先填入,最大为255。 出口参数:输入字符串存储在DS:DX指示的缓冲区。第二字节为实际输入字符数(在输入字符串后自动写入),从第三字节开始存放输入的字符串。实际输入字符多于预设数时,多出的字符被丢弃。用户按回车键结束输入。 【例6.32】用0AH号DOS系统功能调用从键盘输入一个字符串 SBUF DB 21 ;定义缓冲区,第1字节为输入的最大字符数 DB 0 ;用于存放实际输入的字符数 DB 21 DUP(0) ;用于存放输入的字符串 MOV DX,SEG SBUF ;取得SBUF的段地址 MOV DS,AX ;设置数据段DS,如在程序开始处已设置,此处可省略 MOV DX,OFFSET SBUF ;设置缓冲区偏移地址 MOV AH,0AH ;设置子功能号 INT 21H ;系统功能调用,2019/9/4,43,6.3.3 ROM-BIOS功能调用,ROM-BIOS也为程序员提供了大量的系统功能子程序,其功能更为强大。 一、一个字符的输出 中断类型:10H。 子功能号:AH=0EH。 入口参

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1