2012年微机原理课程上机实验指导书 - 图文

更新时间:2024-03-08 21:07:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第一部分 汇编语言程序设计实验

实验一 汇编语言编程基础

汇编语言是一种面向机器的“低级”语言,是计算机能够提供给用户的最快而最有效的语言,也是能够利用计算机所有硬件特性并能直接控制硬件的唯一语言。要真正理解计算机的工作过程,理解计算机程序的执行过程,就必须学习汇编语言。也正是因为如此,汇编语言程序设计是计算机专业和电子,自动控制等相关专业的重要课程。

但是,对于刚开始学习汇编语言的学生而言,汇编语言的一些命令非常抽象,很难理解,往往学习了很长时间也编不出满意的程序,更别说自如的应用,以致我们认为汇编语言很难掌握,影响我们学习汇编语言的兴趣。实际上,为了掌握好汇编语言,我们可以从熟悉、使用DEBUG调试工具开始,先来分析和读懂一些与硬件相关的小程序,这也是我们实验一的目的。

1.1 汇编语言程序的上机步骤

以下列源程序为例,先学习汇编语言的上机步骤。 文件名为1.asm:

DATA SEGMENT NUM1 DB 35,35H NUM2 DW 35,35H

NUM3 DB 4 DUP (34,3 DUP (34H)) NUM4 DB '34AB'

NUM5 DW '34','AB'

DATA ENDS CODE SEGMENT

ASSUME CS:CODE,DS:DATA

START: MOV AX,DATA MOV DS,AX

MOV BX,OFFSET NUM1 MOV AL,[BX]

MOV BX,OFFSET NUM5 MOV AX,[BX] MOV AH,4CH INT 21H

CODE ENDS

END START

1

一.上机步骤

汇编语言程序MASM软件由EDIT.COM编辑器,汇编MASM.EXE程序,连接LINK.EXE程序以及DUEBUG.EXE调试程序四个部分组成。汇编语言编制完成后,在计算机上的操作过程就分为四个阶段。

1. 编辑EDIT.COM

首先输入源程序,有两种方法:

(1)在记事本里录入,特别注意的是:在保存时文件格式必须选择所有文件,文件后缀名为.ASM, 即保存时文件名为XXX.asm。

(2)双击MASM软件中的编辑软件EDIT.COM文件框,在EDIT下输入源程序。用ALT+F键打开file菜单,用其中的save功能键将文件存盘。特别注意的是:汇编语言源程序文件的后缀必须为.asm,即保存时文件名为XXX.ASM。

图1-1 EDIT编辑界面

2.用汇编程序MASM.Exe对源程序.ASM文件汇编,生成目标文件.OBJ

汇编阶段的任务是把汇编语言源程序翻译成机器代码(称为目标),产生二进制格式的目标文件XXX.OBJ(名字与源程序名相同,只是后缀名不同),如果源程序有语法错误,则汇编过程结束后,MASM.EXE汇编程序会指出源程序中错误的行号和错误的原因,我们可以再用编辑程序EDIT.com来修改源程序中的错误,汇编无错后,方可得到正确的.OBJ目标文件,才能进行下一部的连接LINK。

双击MASM软件中的MASM.Exe文件框,在命令行后键入源程序名XXX.asm,(如果源程序与MASM软件在同一路径下,可以只键入文件名,而不要后缀),如以下界面:

2

图1-2 MASM编译1.asm文件无错误时的界面

3.连接LINK.EXE

由于汇编所得到的目标代码的存放地址并不是可执行的绝对地址,而是浮动的相对地址, 汇编产生的目标文件.OBJ还不能在计算机上运行,需要用连接程序LINK.EXE把目标文件.OBJ文件转换为可执行文件XXX.EXE文件.

双击MASM软件中的LINK.Exe文件框,在命令行后键入目标文件名XXX.OBJ(如果源程序,目标文件与MASM软件在同一路径下,可以只键入文件名,而不要后缀),如以下界面:

图1-3 LINK连接1.OBJ文件界面

如果连接没有错误,就会产生一个XXX.EXE的可执行文件,如果.OBJ文件有错误,连接时会指出错误的原因。对于无堆栈警告(warning: no stack segment)的提示,可以不予理睬,它是由于我们在源程序中没有定义堆栈段的原因,对于比较小的程源序和不需要再特别定义堆栈段的源程序,我们可以不定义堆栈段,它并不影响程序的正确执行。反而,如果连接时有其他的错误,则要检查并修改源程序XXX.ASM,然后再重新汇编MASM.EXE,连接link.exe的步骤,直到得到正确的XXX.EXE文件为止。

3

4.运行和调试DEBUG.exe

运行可执行文件,即双击XXX.EXE文件框即可,或在DOS下运行此程序, E:\\XXX.EXE。

1.2熟悉、使用DEBUG调试工具

以下重点介绍一些调试命令:以1.asm源程序为例:

图1-4 运行和调试DEBUG界面

1)N命令:用于指定进行读写的磁盘上的文件。 命令格式:N[path][filename]

如: -n 1.exe指定要装载(Load)或写入磁盘(Write)的文件名。

2)L命令:将指定的文件装入内存中 命令格式:L 回车键 -l 回车键

3)反汇编命令U

就是将存放在制定范围内的目标代码,反汇编成8086/8088的汇编指令格式,并按目标代码首地址,目标代码和对应的源指令的格式,在屏幕上显示出来。把目标代码反汇编后,用户可以方便地知道,程序从什么地址开始执行,执行的是哪一条指令,执行到什么地址为止。

命令格式:U[地址范围] -u

13FE:0000 B8FC13 MOV AX,13FC 13FE:0003 8ED8 MOV DS,AX 13FE:0005 BB0000 MOV BX,0000 13FE:0008 8A07 MOV AL,[BX]

4

13FE:000A BB1A00 MOV BX,001A 13FE:000D 8B07 MOV AX,[BX] 13FE:000F B8004C MOV AX,4C00 13FE:0012 CD21 INT 21

13FE:0014 0000 ADD [BX+SI],AL 13FE:0016 0000 ADD [BX+SI],AL 13FE:0018 0000 ADD [BX+SI],AL 13FE:001A 0000 ADD [BX+SI],AL 13FE:001C 0000 ADD [BX+SI],AL 13FE:001E 0000 ADD [BX+SI],AL

13FE为CS即代码段的段基地址,0000,0003,0005是偏移地址,B8FC13等是机器码(由代码段中的二进制机器指令反汇编得到)也就是程序在机器中的代码, MOV AX,13FC是助记符,帮助记忆机器中的指令。(源指令)

4)运行命令:

T命令:单步运行命令

以1.EXE调试为例,单步运行二次

13FE:0000 B8FC13 MOV AX,13FC 13FE:0003 8ED8 MOV DS,AX 13FE:0005 BB0000 MOV BX,0000 13FE:0008 8A07 MOV AL,[BX] 13FE:000A BB1A00 MOV BX,001A 13FE:000D 8B07 MOV AX,[BX] 13FE:000F B8004C MOV AX,4C00 13FE:0012 CD21 INT 21

13FE:0014 0000 ADD [BX+SI],AL 13FE:0016 0000 ADD [BX+SI],AL 13FE:0018 0000 ADD [BX+SI],AL 13FE:001A 0000 ADD [BX+SI],AL 13FE:001C 0000 ADD [BX+SI],AL 13FE:001E 0000 ADD [BX+SI],AL -t

AX=13FC BX=0000 CX=0034 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=13EC ES=13EC SS=13FC CS=13FE IP=0003 NV UP EI PL NZ NA PO NC 13FE:0003 8ED8 MOV DS,AX -t

AX=13FC BX=0000 CX=0034 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=13FC ES=13EC SS=13FC CS=13FE IP=0005 NV UP EI PL NZ NA PO NC 13FE:0005 BB0000 MOV BX,0000

可以看到机器随机分配给该程序的数据段的段基地址被AX赋予给DS。 该程序的代码段的段基地址为13FE,数据段的段基地址为13FC 。

5

单步执行命令T执行一条命令,并显示CPU中寄存器中的内容和要执行的下一条命令,大家可以看到AX,BX,CX等寄存器的内容,T命令可以跟踪程序中的每一条指令的执行情况.

P命令:也是单步运行命令。但是P命令对于每一条指令语句都是一次执行完成. 比如CALL、LOOP和DOS功能调用的INT n等指令语句T命令能在程序的执行中,跟随IP指示的地址,跟踪指令的执行,而P命令则是按指令语句,续进执行的.在调试中,用户可根据需要,选择不同的运行程序命令,以适应调试的要求。

5)G (Go)命令:连续执行内存中的程序,还可以在程序中设置断点,逐段地执行程序,以便一段一段地对程序进行调试。

命令格式:G[ =address[address[address?]]

其中第一个参数=address,规定了执行的起始地址,即以CS的内容为段地址,以等号后面的地址为偏移地址,在输入时,等号是不可缺少的,若不输入起始地址,则以CS:IP为起始地址,后面的地址参数是断点地址。如果在G命令中没有设置断点,或设有断点但程序在执行中未能到达断点处,这时程序将一直运行,直至结束。在结束时显示提示信息“Program terminated normally\。

在G命令中可以设置断点,格式为G=0000 000D 13FE:000D 8B07 MOV AX,[BX] 13FE:000F B8004C MOV AX,4C00 13FE:0012 CD21 INT 21

AX=1323 BX=0000 CX=0034 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=13FC ES=13EC SS=13FC CS=13FE IP=000A NV UP EI PL NZ NA PO NC 13FE:000A BB1A00 MOV BX,001A -可以看到AL中的数为23 再设置一次断点G=0000 000F -g=0000 000f

AX=3334 BX=001A CX=0034 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=13FC ES=13EC SS=13FC CS=13FE IP=000F NV UP EI PL NZ NA PO NC 13FE:000F B8004C MOV AX,4C00 -

可以看到AX=3334

6)D (Dump)命令:显示指定范围(range)内的内存单元的内容。 其中,参数范围(range)有以下两种表示方式: a) 第一种表示方式:Addrl Addr2

这里Addrl和Addr2分别代表待显示内存单元的首地址和末地址。 2) 第二种表示方式:Addrl L Value

这里表示显示从地址Addrl开始、长度为Value个字节的内存单元。例如下面两条命令是等效的。

一D 200 2FF

6

—D 200 L 100

显示内容分为三部分。最左边是本行内存单元首地址(XXXX:XXXX),第二部分是以十六进制形式显示的相继各字节单元的内容,前后八个单元间用符号“—”隔开。第三部分是本行显示的十六进制值所对应的ASCII字符。如果某十六进制值的ASCII字符是不可显示的,便以“.”代替。注意,每行只显示16个单元的内容,而且每行的首地址都是

16的整倍数,或者说,每行的首地址都是以16为边界的。 对于D命令,又有两种简化格式,如: 一D 200

显示从DS:0200单元开始的80H个单元的内容,即在只给定第一个地址的命令中,约定隐含L 80参数。

一D

除第一次从DS:100开始,显示80H个单元的内容外,以后都继前次地址之后,依次显示80H个单元的内容。

-d

13FE:0000 B8 FC 13 8E D8 BB 00 00-8A 07 BB 1A 00 8B 07 B8 ................ 13FE:0010 00 4C CD 21 00 00 00 00-00 00 00 00 00 00 00 00 .L.!............ 13FE:0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FE:0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FE:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FE:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FE:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FE:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 我们从内存单元偏移地址[0000]单元开始, -d0

13FC:0000 23 35 23 00 35 00 22 34-34 34 22 34 34 34 22 34 #5#.5.\13FC:0010 34 34 22 34 34 34 33 34-41 42 34 33 42 41 00 00 44\13FC:0020 B8 FC 13 8E D8 BB 00 00-8A 07 BB 1A 00 8B 07 B8 ................ 13FC:0030 00 4C CD 21 00 00 00 00-00 00 00 00 00 00 00 00 .L.!............ 13FC:0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FC:0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FC:0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 13FC:0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ -可以看到从偏移地址[0000]单元开始显示内存单元的内容。

7)R (Register)命令

格式:R [register_name] 功能:显示CPU中的一个或所有16位寄存器(包括标志寄存器)的内容。对于标志寄存器来说,显示的是各标志位的状态(置位/复位)。

-r

AX=3334 BX=001A CX=0034 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=13FC ES=13EC SS=13FC CS=13FE IP=000F NV UP EI PL NZ NA PO NC 13FE:000F B8004C MOV AX,4C00

-命令Rregister_name不但能显示出该寄存器的当前值,而且还显示提示符“:”。这时

7

只要输入新的值,便可更新该寄存器的内容。若只按回车键,则寄存器的值将保持不变。例如命令:

-r

AX=3334 BX=001A CX=0034 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=13FC ES=13EC SS=13FC CS=13FE IP=000F NV UP EI PL NZ NA PO NC 13FE:000F B8004C MOV AX,4C00 -rax AX 3334 :6677 -r

AX=6677 BX=001A CX=0034 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 DS=13FC ES=13EC SS=13FC CS=13FE IP=000F NV UP EI PL NZ NA PO NC 13FE:000F B8004C MOV AX,4C00

RDS,RCS命令可以修改当前段的地址。同学们下来可以试以下。 8)- F是标志寄存器的名字。命令RF将显示各状态位的当前状态,其后显示提示符“一”,这时只要输入合法的标志(对顺序无要求),便可修改标志位状态,若只按回车键,则标志位的状态将保持不变。如命令:

一RF

NV UP DI NG NZ AC PE NC—PL EI CY

显示了F中的各状态位,其后又通过输入PL EI CY,修改了对应的标志位。 -rf

NV UP EI PL NZ NA PO NC -pl ei cy -rf

NV UP EI PL NZ NA PO CY -

9) E (Enter)命令

格式:E address [1ist]

功能:用键入的字节(Byte)值或替换值(字节)列表修改指定内存单元的内容参数,address表示待修改的内存单元的首地址,list是一个选择项,它表示替换值(字节)列表。

1) E address

在该命令格式中,没有给出替换值。DEBUG自动显示起始地址和它的内容,并等待用户键入替换值。用户这时可选择按空格键(Space)、横杠键(一)或回车键(Enter),以实现不同的操作:

按回车键(Enter)——结束E命令。

按空格键(Space)——自动显示下一个内存单元的内容,并等待键人替换值。按照这种方式,一直进行下去,直到按回车键(Enter),才结束E命令。

按横杠键(一)一一自动显示前一个内存单元的内容,并等待键人替换值。按照这种方式,一直进行下去,直到按回车键,才结束E命令。

在上述两种修改方式中,如果在未键入替换值的情况下就按回车键,这时该单元的内容保持不变并结束E命令;如果只按空格键或横杠键,不键入替换值,则只显示内存单元的内容。

-e

8

^ Error -e0

13FC:0000 23. 35. 23. 00. 35. 00. 22. 34. 13FC:0008 34. 34. 22. 34. 34. 34. 22. 34. 13FC:0010 34. 34. 22. 34. 34. 34. 33. 34. 13FC:0018 41. 42. 34. 33. 42. 41. 00. 00. 13FC:0020 B8. FC. 13. 8E. D8. BB. 00. 00. 13FC:0028 8A. -e0

13FC:0000 23. 35.67 23.34 00. 35. 00. 22. 34. 13FC:0008 34. 34. 22. -e0

13FC:0000 23. 67. 34. 00. 35. 00. 22. 34. 13FC:0008 34. 34. 22. 34. 34. 34. 22. 34. 13FC:0010 34. 34. 22. 34. 34. 34. 33. 34. 13FC:0018 41. 42. 34. 33. 42. 41. 00. 00. . -

-e0003 显示从[0003]开始的内容

13FC:0003 00. 35. 00. 22. 34.

13FC:0008 34. 34. 22. 34. 34. 34. 22. 34. 13FC:0010 34. 34. 22. 34. 34. 34.

10)F (Fill) 命令 格式:F range list

功能:用list所表示的字节值对指定范围(range)的内存单元进行填充在命令中,若指定范围的内存单元数多于list中的填充字节数,则F命令将反复使用填充字节,直到填满指定范围中的每个单元;若内存单元数少于填充字节数,则F命令将只使用list中的前面若干个字节值,填充各个内存单元。

-f ds:0003 L 10 6 -e0

13FC:0000 23. 67. 34. 06. 06. 06. 06. 06. 13FC:0008 06. 06. 06. 06. 06. 06. 06. 06. 13FC:0010 06. 06. 06. 34. 34. 34. 33. 34. 13FC:0018 41. 42. 34. 33. 42. 41. 00.

11)A(Assemble)命令 格式:A [address]

功能:接收从键盘键入的8086/8088指令,将其汇编成目标代码,并存放在内存单元中。

参数address是指定存放目标代码的起始地址,其后指令的起始地址将由系统自动依次

9

安排。

一A CS:100 ;从CS:100H开始,编写程序 1409:001C 0000 ADD [BX+SI],AL 1409:001E 0000 ADD [BX+SI],AL -a

1409:0000 -a cs:000a

1409:000A mov bx,0009 1409:000D

这时我们再反汇编一下,可以看到,程序发生了变化。 -u0

1409:0000 B80714 MOV AX,1407 1409:0003 8ED8 MOV DS,AX 1409:0005 BB0000 MOV BX,0000 1409:0008 8A07 MOV AL,[BX] 1409:000A BB0900 MOV BX,0009 1409:000D 8B07 MOV AX,[BX] 1409:000F B8004C MOV AX,4C00 1409:0012 CD21 INT 21

A命令只是在DEBUG下,汇编程序,不能存盘,临时修改看结果。

12)Q命令:结束DEBUG。

至此,通过调试示例程序,学习了DEBUG调试命令,并了解了8088汇编语言的段结构、常用的指令与伪指令、存储空间的分配,调试程序的方法,但这还只是简单的程序,调试复杂的程序比此例要复杂的多,还需要我们在学习过程中,勤动手,多动脑,加强练习,在实践中进步。

1.3汇编语言程序上机操作和调试训练

一。上机目的:

了解并逐步熟悉汇编语言的编辑方法及特点.

复习8088汇编语言的段结构、常用的指令与伪指令、存储空间的分配等。 掌握汇编语言的编辑、汇编及连接的过程。

了解并逐步掌握运用DEBUG进行调试汇编语言程序。 二。实验内容:

运用8086汇编语言,编辑多字节非压缩型BCD数除法的简单程序,文件名取为*.ASM。 运用MASM﹒EXE文件进行汇编,修改程序中的各种语法错误,直至正确,形成*.OBJ文件。

运用LINK.EXE文件进行连接,形成*.EXE文件。

仔细阅读和体会DEBUG调试方法,掌握各种命令的使用方法。 运用DEBUG。EXE文件进行调试,使用单步执行命令—T两次,观察寄存器中内容的变化,

10

使用察看存储器数据段命令—D,观察存储器数据段内数值。

再使用连续执行命令—G,执行程序,检查结果是否正确,若不正确可使用DEBUG的设置断点,单步执行等功能发现错误所在并加以改正。

程序清单:

多字节非压缩型BCD数除法 (96875/5=19375) DATA SEGMENT

A DB 9,6,8,7,5 B DB 5

C DB 5DUP (0) N EQU 5 DATA ENDS CODE SEGMENT

ASSUME CS:CODE;DS:DATA;ES:DATA, START MOV AX,DATA MOV DS,AX MOV ES,AX CLD

LEA SI,A

LEB DI,C MOV CX,N

MOV AH,0 LP1: LODSB AAD

DIV B STOSB

LOOP LP1 MOV CX,N LEA DI,C

LP2: MOV DL,[DI]

MOV AH,2 开始 INT 21H

DEC DI 设置被除数、商的地址指针 LOOP LP2 设置单位除法次数计数器 MOV AH,4CH

INT 21H 取被除数一位作十进制调整 CODE: ENDS

END START 作字节除法、存商

N 被除数各位已除完? Y 显示运算结果

结束 11

三。实验报告要求:

1)写出本次试验报告的实验目的,内容,正确的程序清单,适当的中文注释以及程序框图。

2)指出本实验给出的源程序错误,并加以改正。 3)给出实验结果。 4)调试的心得体会。

实验二 设计汇编语言程序

要设计汇编语言程序,我们先复习一些基本的指令。 1.加法指令

(1)ADD---加法指令

格式:ADD 目的操作数,源操作数

功能:目的操作数 目的操作数+源操作数 (2)ADC---带进位的加法指令 格式:ADC 目的操作数,源操作数

功能:目的操作数 目的操作数+源操作数+CF(CF=1,有进位) (3)INC---增量指令 格式:INC 目的操作数

功能:目的操作数 目的操作数+1 2.减法指令

(1)SUB——减法指令

格式:SUB 目的操作数,源操作数

功能:目的操作数 目的操作数-源操作数 (2)SBB——带借位的减法指令 格式:SBB 目的操作数,源操作数

功能:目的操作数 目的操作数-源操作数-CF (3)DEC——减量指令 格式:DEC 目的操作数

功能:目的操作数 目的操作数-1 (4)NEG 求补指令 格式:NEG 目的操作数

功能:目的操作数 0-目的操作数 3.乘法和除法指令

(1)MUL——无符号数乘法 格式:MUL 源操作数

功能:8位源操作数时:AX (AL)×源操作数

16位源操作数时:DX,AX (AX)×源操作数 32位源操作数时:EDX,EAX (EAX)×源操作数 (2)IMUL有符号数乘法 格式1: IMUL 源操作数

功能:8位源操作数时:AX (AL)×源操作数

12

16位源操作数时:DX,AX (AX)×源操作数 32位源操作数时:EDX,EAX (EAX)×源操作数 格式2: IMUL 目的操作数, 源操作数

功能:目的操作数 目的操作数×源操作数

格式3: IMUL 目的操作数,源操作数1,源操作数2 功能:目的操作数 源操作数1×源操作数2 (3)DIV ——无符号除法 格式:DIV 源操作数 功能:8位源操作数时:(AX)÷源操作数,AL 商,AH 余数 16位源操作数时:(DX,AX )÷源操作数,AX 商,DX 余数 32位源操作数时:(EDX,EAX)÷源操作数,EAX 商 ,EDX 余数 (4)IDIV——有符号除法 格式:IDIV 源操作数 功能:8位源操作数时:(AX)÷源操作数,AL 商,AH 余数 16位源操作数时:(DX,AX )÷源操作数,AX 商,DX 余数 32位源操作数时:(EDX,EAX)÷源操作数,EAX 商 ,EDX 余数

实验

2.1 简单程序设计

实验目的

理解各种指令的功能。 进一步学习程序的调试。

使用以上指令,我们可以进行一些表达式的计算。

练习1. 实验题目:编程计算下列表达式:A=90,B=-70,C=5,Y均为有符号数, 计算Y=2×(A+B)+(A×C)÷5

要编写一些稍微复杂的程序,我们会遇到一段程序被反复执行,这样,我们会用到LOOP指令。使用该指令时,需在CX中装入循环次数。

练习2.码转换程序设计

编制程序,把十进制数15786转化成二进制数。

提示:15786=1×10×10×10×10+5×103+7×102+8×10+6 循环CX=5

实验要求:1.绘出练习1和2的程序流程图。 2编写完整的程序,上机调试。

3使用DEBUG调试命令,查看中间结果,并查看最终结果。

大多数的程序,都有人机对话的过程。也就是说,我们从键盘上输入程序所需要的控制信息和数据,并把程序的运行结果和运行状态显示出来。这就涉及到字符及字符串的输入输出。

1. 字符的输出 (1)输出单个字符

DL 待输出字符的ASCII码 AH =02

13

INT 21H

输入的字符放在AL中,并显示在屏幕上。 (2)输出一个字符串

DS: DX 待输出字符串的首地址 AH=09H Int 21H

2.字符的输入 (1)输入单个字符 AH=01 INT 21H

输入的字符放在AL中 (2)AH=07 INT 21H

输入的字符放在AL中,不会显示在屏幕上(无回显)。 3.字符串的输入

DS:DX 输入缓冲区首地址 AH=0AH INT 21H

一行字符以回车键作为结束的标志。假如:一行最多不超过250个字符(不含回车键),输入缓冲区格式如下:BUFFER DB 250 ,? ,250 DUP(?)

缓冲区由3个部分组成:

第一字节 :输入字符存放区的大小。

第二字节:初始状态为空。从服务程序返回后,由服务程序填入实际的字符个数,不包括回车。

第三字节之后:输入字符存放区,存放输入的字符和回车。

练习3.编制程序,从键盘输入最多5个数,求他们的和,存入SUM。 实验要求:1.绘出程序流程图。

2编写完整的程序,上机调试。

3要求编制的程序最终求和的结果要显示在屏幕上。 4.写实验报告中程序要加中文注释。

实验2.2 汇编语言程序设计

---- 循环结构程序

几乎所有的应用程序都离不开循环结构。 循环结构一般有以下4个部分组成。

1初始化部分:为循环做准备,如累加器清零,设置地址指针和计数器的初始值。 2.工作部分:实现循环的基本操作,也就是需要重复执行的一段程序。 3.修改部分:修改指针,计数器的值,为下一个循环做准备。 4.控制部分:判断循环条件,结束循环或继续循环。

14

练习1.用“冒泡“法对一组数300,250,280,240,260,按从小到大的顺序排列。

提示:用冒泡的方法对一组数据元素排序,它的基本方法是:将相邻的两个元素通过比较进行排序,通过多次,多遍的邻元素排序,实现整个一组数的排序。

对于5(N)个元素,整个排序通过4遍(=N-1)邻元素排序完成。每一遍的排序由若干次邻元素的排序组成。

4遍排序中,邻元素的排序依次为4,3,2,1遍。完成第一遍排序后,最大数沉底,已经到达它应占据的位置,不需要参加下一遍的排序。

外循环的次数为CX=4次(N-1),内循环的次数为4,3,2,1(DEC CX) 排序遍数 1 2 3 4 实验要求:

本遍排序前 第一次排序后 240,260 260,300 280,300 280,300 第二次排序后 240,260 260,300 280,300 第三次排序后 300,260 280,300 第四次排序后 260,300 300,250,280,250,300,280,250,280,300,250,280,240,250,280,240,240,260 260,300 280,300 280,300 250,280,240,250,280,240,250,240,280,250,240,260,250,240,260,250,240,260,240,250,260,240,250,260,240,250,260,1. 编制程序,从键盘输入300,250,280,240,260这五个数,并思考如何输入任意五个数,五个数可以有一位数,二位数,三位数,四位数,五位数,混合输入比较大小;

2. 对这组数用冒泡法进行排序,并输出原始数据及排序后数据,两两数据之间用空格分隔;

3. 利用DEBUG调试工具,用D0命令,查看排序前后,内存数据的变化,以及会用调试命令查看程序运算中寄存器中的值;

4. 去掉最大和最小的两个值,求出其余值的平均值,并输出最大值,最小值和平均值;

5. 用压栈PUSH和出栈POP指令“先进后出”的特点,设计算法将平均值按位逐个输出(即输出263);

6. 用移位指令将平均值以二进制串的形式输出。

7. 设计程序要有模块化的思想,用子程序实现不同的功能; 8. 所有数据输出前要用字符串的输出指令,进行输出提示(如:zui da zhi shi : 300等),所有数据结果能清晰地显示在电脑屏幕上。

实验报告:

整理出运行正确的程序清单(加以注释)。并给出程序流程图。

15

第二部分 接口程序设计

第三次实验 8253定时器/计数器与接口实验

------乐曲程序

计算机是如何产生音乐和声响的呢?原来在计算机中有一个可编程时间间隔定时器8253,它能根据程序提供的计数值和工作模式,产生各种形状和各种频率的计数/定时脉冲,提供给系统的各个部件使用。它还可以产生不同频率的脉冲作为扬声器的声源。

在8253定时器内部有3个独立工作的计数器:Counter0, Counter1, Countre2,每个计数器都分配有一个端口地址,分别是40H,41H,42H。8253内部还有一个公用的控制寄存器,端口地址为43H,端口地址输入到8253的CS,A1,A0端,分别对三个计数器和控制器寻址。 对8253编程时,先要设定控制字,以选择计数器,确定工作模式和计数值的格式,每个计数器由三个引脚与外部联系,CLK为时钟输入端,GATA为门控制信号输入端,OUT为计数/定时信号输入端。每个计数器是以倒计数的方式计数,也就是说,从计数初值开始逐次减1,直到减为0为止。

端口地址与计数器的关系: 40H 41H 42H 43H 选中计数器0:作为定时器为系统日时钟提供计时基准 选中计数器1:作为定时器使用 选中计数器2:用来控制扬声器发声 公用的控制器:分别对三个寄存器和控制器寻址

那么,如何触动扬声器发出声音呢?原来PC机的主音箱上装有一只小喇叭,由定时器8253和并行接口芯片8255(可编程外围接口芯片)控制其发声,8255包括三个8位寄存器,两个用于输入功能,一个用于输出功能。输入寄存器分配的I/O端口地址为60H和62H,输出寄存器分配的I/O端口地址为61H。8253定时器计数器2连接到扬声器,其电路如下:

8253 DRIVER 1.9318MHZ CLK 喇叭 OUT2 与门 8255

PB0 GATE2 PB1

装入计数器2的计数初值为533H(1.19318MHz/896Hz=1331=533H),这样,得到的控制

16

字为10110110B=0B6H,即选中计数器2,读/写,工作方式三(方波发声器),二进制。

计数器2的初始化程序为: MOV AL,0B6H OUT 43H,AL

1) 计算计数值程序段:

MOV DI, 给定频率 MOV DX, 12H MOV AX, 34DCH DIV DI

AX中即为计数值。

2) 打开扬声器发声,8255PB0,PBI送出高电平:

IN AL , 61H OR AL , 3 OUT 61H , AL 3)关闭扬声器,停止发声:

IN AL ,61H AND AL , 0FCH OUT 61H, AL

两只老虎的音频表定义在数据段中,如下:

STACK SEGMENT

DW 100 DUP(?) STACK ENDS

DATA SEGMENT

MUSIC DW 2 DUP(262,294,330,262) ; 频率表,1231;1231 DW 2 DUP(330,349,392) ;345;345;

DW 2 DUP(392,440,392,349,330,262) ;565431;565431

dw 2 dup(294,196,262),0 ;251;251,0表示结束

TIME DW 10 DUP(250*50),500*50,250*50,250*50,500*50 ;节拍表 DW 2 DUP(120*50,120*50,120*50,120*50,250*50,250*50) DW 2 DUP(250*50,250*50,500*50)

N EQU 32 ;32个音符 DATA ENDS

二.实验目的:

学习8253计数器2输出方波信号用以驱动扬声器发声的原理,通过程序设置计数器

17

2的输出波形的频率和延续时间,控制扬声器的音调和发生长短。

三.实验内容:

1.设计程序让微机演奏一段两只老虎的乐曲。

2.思考如何让PC机演奏一遍,两遍以及数遍这段两只老虎的乐曲,并修改程序实现。

四.实验报告:

整理出运行正确的源程序清单(加以中文注释),并给出详细程序流程图。

第四次实验 8253定时器/计数器接口实验

-----键盘控制发声程序

音符和频率之间有一定的对应关系,如果计算机键盘上的数字键和音符,频率也形成一种对应关系,则可以通过键盘控制扬声器发出各种音符声音,这是计算机键盘就变成了电子琴琴键盘,就可以用它弹奏出简单的音乐。我们让数字键1-8对应一个音阶的八个音符。

弹奏时,对应乐谱上的1(C音符),按下数字键“1”(ASCII码为31H),程序的工作就是要接受这个键,并将频率表中和它对应的频率值262Hz送给发声程序,以发出1(C音符)的音调。按下数字键“2”(ASCII码为32H),程序就将292Hz的频率值送给发声程序,从而发出2(D的音调)。按下数字键“8”,将发出比第一个C高八度的音调,音符的频率表作为数据定义在数据段中。流程图如下:

初始化

键盘输入

编程提示:

是结束符 1.数据段可以定义如下:

DATA DW 262 ;1(C) Y DW 294 ;2(D) BX 频率表地址 DW 330 ;3(E)

结束 DW 349 ;4(F)

DW 392 ;5(G) ?1?—?8’? DW 440 ;6(A) N DW 494 ;7(B) DI 频率值 DW 523 ;8(C)

BX 持续时间 DATA ENDS 调用发声程序

18

2.从键盘输入一个键值,可以用BIOS 16H中断,AL中回送的是键的ASCII码,AH中回送的是键的扫描码。也可以用DOS的键盘输入功能。 MOV AH,07 ;功能号AH=07

INT 21H ;DOS 21号中断

一.实验内容:利用DOS的键盘管理功能,将PC机变为一个具有简单功能的电子琴。

二.实验报告:整理出运行正确的源程序清单(加以中文注释)。

附录A 标准ASCII码字符表

19

ASCII码 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH 0FH 10H 11H 12H 13H 14H 15H 16H 17H 18H 19H 1AH 1BH 1CH 1DH 1EH 1FH 字符 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US ASCII码 20H 21H 22H 23H 24H 25H 26H 27H 28H 29H 2AH 2BH 2CH 2DH 2EH 2FH 30H 31H 32H 33H 34H 35H 36H 37H 38H 39H 3AH 3BH 3CH 3DH 3EH 3FH 字符 SP ! ″ # ﹩ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? ASCII码 40H 41H 42H 43H 44H 45H 46H 47H 48H 49H 4AH 4BH 4CH 4DH 4EH 4FH 50H 51H 52H 53H 54H 55H 56H 57H 58H 59H 5AH 5BH 5CH 5DH 5EH 5FH 字符 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \\ ] ^ _ ASCII码 60H 61H 62H 63H 64H 65H 66H 67H 68H 69H 6AH 6BH 6CH 6DH 6EH 6FH 70H 71H 72H 73H 74H 75H 76H 77H 78H 79H 7AH 7BH 7CH 7DH 7EH 7FH 字符 ˋ a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ DEL 20

附录B 键盘扫描码表

键 ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 ˋ~ 1! 2@ 3# 4﹩ 5% 6^ 7& 8* 9( 0) -_ = + \\ | Back Space Tab Q W E R T Y 接通 扫描码 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 2B 0E 0F 10 11 12 13 14 15 断开 扫描码 81 BB BC BD BE BF C0 C1 C2 C3 C4 D7 D8 A9 82 83 84 85 86 87 88 89 8A 8B 8C 8D AB 8E 8F 90 91 92 93 94 95 键 U I O P [{ ]} Enter Caps Lock A S D F G H J K L ; : ″ ′ 左Shift Z X C V B N M , < . > / ? 右Shift 左Ctrl 左Windows 左Alt Space 接通 扫描码 16 17 18 19 1A 1B 1C 3A 1E 1F 20 21 22 23 24 25 26 27 28 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 1D E0 5B 38 39 断开 扫描码 96 97 98 99 9A 9B 9C BA 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 AA AC AD AE AF B0 B1 B2 B3 B4 B5 B6 9D E0 DB B8 B9 键 右Alt 右Windows Application 右Ctrl Print Screen Sys Rq Scroll Lock Pause Break Insert Home Page Up Delete End Page Down ↑ ← ↓ → Num Lock ÷(/) ×(*) - Home 7 ↑ 8 PaUp 9 ← 4 5 → 6 + End 1 ↓ 2 PgDn 3 Ins 0 Del. Enter (数字键盘) 接通 扫描码 E0 38 E0 5C E0 5D E0 1D E0 37 46 E1 1D 45 E1 9D C5 E0 52 E0 47 E0 49 E0 53 E0 4F E0 51 E0 48 E0 4B E0 50 E0 4D 45 E0 35 37 4A 47 48 49 4B 4C 4D 4E 4F 50 51 52 53 E0 1C E0 D2 E0 C7 E0 C9 E0 D3 E0 CF E0 D1 E0 C8 E0 CB E0 D0 E0 CD C5 E0 B5 B7 CA C7 C8 C9 CB CC CD CE CF D0 D1 D2 D3 E0 9C - 断开 扫描码 E0 B8 E0 DC E0 DD E0 9D E0 B7 C6

21

附录C 80×86指令系统

1. 指令符号说明 符 号 R8/r16/r32 reg seg mm xmm ac m8/m16/m32/m64/m128 mem I8/I16/I32 imm dst src label m16&32 d8/d16/d32 EA 一个通用8/16/32位寄存器 通用寄存器 段寄存器 整数MMX寄存器:MMX0~MMX7 128位的浮点SIMD寄存器:XMM0~XMM7 AL/AX/EAX累加寄存器 一个8/16/32/64/128位存储器操作数 一个m8或m16或m32存储器操作数 一个8/16/32位立即操作数 一个I8或I16或I32位立即操作数 目的操作数 源操作数 标号 16位段限和32位段基地址 8/16/32位偏移地址 指令内产生的有效地址 说 明

2. 16/32位80×86基本指令 助 记 符 AAA AAD AAM AAS mem, reg/imm ac, imm ADD reg, (dst)←(src)+(dst) mem/imm/reg mem, reg/imm ac, imm AND reg, (dst)←(src)∧(dst) mem/imm/reg mem, reg/imm ac, imm ARPL dst, src BOUND reg, mem BSF r16, r16/m16 r32, r32/m32

调整选择器的RPL字段 测数组下标(reg)是否在指定的上下界(mem)之内。在界内,则往下执行;不在界内,产生INT5 自右向左扫描(src),遇第一个为1的位,则ZF←0,该位位置装入reg;如(src)=0,则ZF←1 22

386起 286起,系统指令 286起 功 能 把AL中的和调整到非压缩的BCD格式 把AX中的非压缩BCD码扩展成二进制数 把AX中的积调整为非压缩的BCD码 把AL中的差调整为非压缩的BCD码 备 注 ADC reg, mem/imm/reg (dst)←(src)+(dst)+Cf 助 记 符 BSR r16, r16/m16 r32, r32/m32 BSWAP r32 BT reg, reg/i8 mem, reg/i8 BTC reg, reg/i8 mem, reg/i8 BTR reg, reg/i8 mem, reg/i8 BTS reg, reg/i8 mem, reg/i8 CALL reg/mem 功 能 自左向右扫描(src),遇第一个为1的位,则ZF←0,该位位置装入reg;如(src)=0,则ZF←1 (r32)字节次序变反 把由(src)指定的(dst)中的位内容选CF 备 注 386起 486起 386起 把由(src)指定的(dst)中的位内容选CF,并把该位取反 386起 把由(src)指定的(dst)中的位内容选CF,并把该位置0 386起 把由(src)指定的(dst)中的位内容选CF,并把该位置1 386起 段内直接:PUSH (IP或EIP),(IP)←(IP)+d16或(EIP)← (EIP)+d32 段内间接:PUSH (IP或EIP),(IP或EIP)←(EA)/reg 段内直接:PUSH CS, PUSH(IP或EIP),(CS)←dst指定的段地址,(IP或EIP)←dst指定的偏移地址 段内间接:PUSH CS, PUSH(IP或EIP),(IP或EIP)← (EA), (CS)←(EA+2)或(EA+4) CBW CDQ CLC CLD CLI CLTS CMC CMP reg, reg/mem/imm mem, reg/imm CMPSB CMPSW CMPSD reg CMPXCHG8B dst CPUID CWD CWDE DAA DAS DEC reg/mem DIV r8/m8 r16/m16 (AL)符号扩展到(AH) (EAX)符号扩展到(EDX) CF←0 DF←0 IF←0 清除CR0中的任务切换标志 进位位变反 (dst)-(src),结果影响标志位 [SI或ESI]-[DI或EDI],SI或ESI,DI或EDI加1或减1 [SI或ESI]-[DI或EDI],SI或ESI,DI或EDI加2或减2 [SI或ESI]-[DI或EDI],SI或ESI,DI或EDI加4或减4 不相等:ZF←0,(ac) ←(src) (EDX,EAX)-(dst),相等:ZF←1,(dst) ←(EDX,EAX) 不相等:ZF←0,(EDX,EAX) ←(dst) (EAX)←CPU识别信息 (AX)符号扩展到(DX, AX) (AX)符号扩展到(E AX) 把AL中的和调整为压缩的BCD格式 把AL中的差调整为压缩的BCD格式 (dst)←(dst-1) (AL)←(AX)/(src)的商,(AH)←(AX)/(src)的余数 (AX)←(DX, AX)/(src)的商,(DX)←(DX, AX)/(src)的余数 386起 386起,系统指令 486起 586起 586起 386起 CMPXCHG reg/mem, (ac)-(dst),相等:ZF←1,(dst) ←(src) 23

助 记 符 r32/m32 ENTER I16, 18 HLT IDIV r8/m8 r16/m16 r32/m32 IMUL r8/m8 r16/m16 r32/m32 IMUL r16/r32, reg/mem imm IN ac, I8/DX INC reg/mem INSB INSW INSD INT I8 (ac)←((I8))或(DX) (dst)←(dst)+1 功 能 (EAX)←(EDX, EAX)/(src)的商,(EDX)←(EDX, EAX)/(src)的余数 建立堆栈帧,I16为堆栈帧字节数,I8为堆栈帧层数 停机 (AL)←(AX)/(src)的商,(AH)←(AX)/(src)的余数 (AX)←(DX, AX)/(src)的商,(DX)←(DX, AX)/(src)的余数 (EAX)←(EDX, EAX)/(src)的商,(EDX)←(EDX, EAX)/(src)的余数 (AL)←(AX)*(src) (EAX)←(AX)*(src) (EDX, EAX) ← (EDX)*(src) (r16)←(r16)*(scr)或(r32)←(r32)*(scr) 备 注 386起 386起 386起 386起 286起 286起 286起 IMUL reg, reg/mem, (r16)←(reg/mem)*imm或(r32)←(reg/mem)*imm ((DI或EDI))←((DX)), (DI或EDI)←(DI或EDI)±1 ((DI或EDI))←((DX)), (DI或EDI)←(DI或EDI)±2 ((DI或EDI))←((DX)), (DI或EDI)←(DI或EDI)±3 PUSH (FLAGS), PUSH (CS), PUSH (IP), (IP)←(i8*4) (CS)←(I8*4+2) 若OF=1,则PUSH (FLAGS), PUSH (CS), PUSH (IP), (IP)←(10H),(CS)←(12H) INVD IRET IRETD JZ/JE JNZ/JNE JS JNS JO JNO JP/JPE JNP/JPO JNC/JNB/JAE JBE/JNA JNBE/JA JL/JNGE JNL/JGE JLE/JNG JNLE/JG

使高速缓存无效 (IP)←POP( ), (CS)←POP( ), (FLAGS)←POP( ) (EIP)←POP( ), (CS)←POP( ), (EFLAGS)←POP( ) d8/d16/d32 如果ZF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果ZF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果SF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果SF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果OF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果OF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果PF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果PF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果CF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果ZF∨CF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果ZF∨CF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果SF⊕OF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果SF⊕OF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果(SF⊕OF) ∨ZF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 d8/d16/d32 如果(SF⊕OF) ∨ZF=0,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 486起,系统指令 386起 D16/d32从386起 JC/JB/JNAE d8/d16/d32 如果CF=1,则(IP)←(IP)+d8或(EIP)←(EIP)+d16/d32 24

助 记 符 JCXZ d8 JECXZ d8/d16/d32 JMP label JMP mem/reg JMP label JMP mem/reg LAHF LAR reg, mem/reg LDS reg, mem LEA reg, mem LEAVE LES reg, mem LFS reg, mem LGDT mem LGS reg, mem LIDT mem LLDT reg/mem LMSW reg/mem LOCK LODSB LODSW LODSD LOOP label LOOPZ/LOOPE label LOOPNZ/LOOPNE label LSL reg, reg/mem LSS reg, mem LTR reg/mem MOV reg/mem/imm mem, reg/imm reg, CR0-CR3 CR0-CR3, reg reg, DR DR, reg reg, SR SR, reg MOVSB 取段界限 功 能 如果(CX)=0, 则(IP)←(IP)+d8 如果(ECX)=0, 则(IP)←(EIP)+d8/d16/d32 段内直接转移,(IP)←(IP)+d8/d16,或(EIP)←(EIP)+d8/d32 段内间接转移,(EIP/IP)←(EA) 段内直接转移,(EIP/IP)←EA,CS←label决定的段基址 段内间接转移,(EIP/IP)←(EA),CS←(EA+2/4) (AH)←(FLAGS的低字节) 取访问权字节 (reg)←(mem), (DS)←(mem+2或4) (reg)←EA 释放堆栈帧 (reg)←(mem), (ES)←(mem+2或4) (reg)←(mem), (FS)←(mem+2或4) 装入全局描述符表寄存器:(GDTR)←(mem) (reg)←(mem), (GS)←(mem+2或4) 装入中断描述符表寄存器:(IDTR)←(mem) 装入局部描述符表寄存器:(LDTR)←(reg/mem) 装入机器状态字(在CR0寄存器中):(MSW)←(reg/mem) 插入LOCK#信号前缀 (AL)←(SI或ESI), (SI或ESI)←(SI或ESI)±1 (AX)←(SI或ESI), (SI或ESI)←(SI或ESI)±2 (EAX)←(SI或ESI), (SI或ESI)←(SI或ESI)±4 (ECX/CX)←(ECX/CX)-1, (ECX/CX)≠0则循环 (ECX/CX)←(ECX/CX)-1, (ECX/CX)≠0且ZF=1则循环 (ECX/CX)←(ECX/CX)-1, (ECX/CX)≠0且ZF=0则循环 备 注 386起 286起,系统指令 286起 386起 286起,系统指令 386起 286起,系统指令 286起,系统指令 286起,系统指令 ESI自386起 自386起 ECX自386起 286起,系统指令 386起 286起,系统指令 386起,系统指令 386起,系统指令 386起,系统指令 386起,系统指令 (reg)←(mem), (SS)←(mem+2或4) 装入任务寄存器 reg, (reg)←(reg/mem/imm) (mem)←(reg/imm) (reg)←(CR0-CR3) (CR0-CR3)←(reg) (reg)←(调试寄存器DR) (DR)←(reg) (reg)←(段寄存器SR) (SR)←(reg) ((DI或EDI))←((SI或ESI)), (SI或ESI)←(SI或ESI) ±1, (DI或EDI)←(DI或EDI)±1 25

助 记 符 MOVSW MOVSD MOVSX reg, reg/mem MOVZX reg, reg/mem MUL reg/mem 功 能 ((DI或EDI))←((SI或ESI)), (SI或ESI)←(SI或ESI) ±2, (DI或EDI)←(DI或EDI)±2 ((DI或EDI))←((SI或ESI)), (SI或ESI)←(SI或ESI) ±4, (DI或EDI)←(DI或EDI)±4 (reg)←(reg/mem符号扩展) (reg)←(reg/mem零扩展) (AX)←(AL)*(r8/m8) (DX, AX)←(AX)*(r16/m16) (EDX, EAX)←(EAX)*(r32/m32) 备 注 386起 386起 386起 386起 386起 NEG reg/mem NOP NOT reg/mem OR reg, reg/mem/imm Mem, reg/imm OUT I8, ac DX, ac OUTSB OUTSW OUTSD POP reg/mem/SR POPA POPAD POPF POPFD PUSH reg/mem/SR/imm POPA POPAD POPF POPFD RCL reg/mem, 1/CL/I8 RCR reg/mem, 1/CL/I8 RDMSR REP REPE/REPZ REPNE/REPNZ RET RET d16 (reg/mem)←(reg/mem) 无操作 (reg/mem)←(reg/mem按位取反) (reg)←(reg)∨(reg/mem/imm) (mem)←(mem)∨(reg/imm) (I8端口)←(ac) ((DX))←(ac) ((DX))←((SI或ESI)), (SI或ESI)←(SI或ESI)±1 ((DX))←((SI或ESI)), (SI或ESI)←(SI或ESI)±2 ((DX))←((SI或ESI)), (SI或ESI)←(SI或ESI)±4 (reg/mem/SR)←((SP或ESP)), (SP或ESP)←(SP或ESP)+2或4 出栈送16位通用寄存器 出栈送32位通用寄存器 出栈送FLAGS 出栈送EFLAGS ((SP或ESP))←(SP或ESP)-2或4 ((SP或ESP))←(reg/mem/SR/imm) 16位通用寄存器进栈 32位通用寄存器进栈 FLAGS进栈 EFLAGS进栈 带进位循环左移 带进位循环右移 读模型专用寄存器:(EDX, EAX)←(MSR[ECX]) (CX或ECX)←(CX或ECX)-1, 当(CX或ECX)≠0,重复执行后面的指令 (CX或ECX)←(CX或ECX)-1, (CX或ECX)≠0且ZF=1,重复执行后面的指令 (CX或ECX)←(CX或ECX)-1, (CX或ECX)≠0且ZF=0,重复执行后面的指令 段内:(IP)←POP( ), 段间:(IP)←POP( ), (CS)←POP( ) 段内:(IP)←POP( ), (SP或ESP)←(SP或ESP)+d16 段间:(IP)←POP( ), (CS)←POP( ), (SP或ESP)←(SP或ESP) 286起 386起 386起 imm自386起 286起 386起 386起 I8自386起 I8自386起 586起 26

助 记 符 +d16 ROL reg/mem, 1/CL/I8 ROR reg/mem, 1/CL/I8 RSM SAHF SAL reg/mem, 1/CL/I8 SAR reg/mem, 1/CL/I8 SBB reg, reg/mem/imm Mem, reg/imm SCASB SCASW SCASD SETcc r8/m8 SGDT mem SHL reg/mem, 1/c1/i8 i8/CL SHR reg/mem, 1/c1/i8 i8/CL SIDT mem SLDT reg/mem SMSW reg/mem STC STD STI STOSB STOSW STOSD STR reg/mem SUB mem/imm/reg mem, reg/imm ac, imm TEST 逻辑右移 循环左移 循环右移 从系统管理方式恢复 功 能 备 注 I8自386起 I8自386起 586起,系统指令 I8自386起 I8自386起 386起 386起 386起,系统指令 I8自386起 386起 (FLAGS的低字节)←(AH) 算术左移 算术右移 (dst)←(dst)-(src)-CF (AL)-((DI或EDI)),(DI或EDI)-(DI或EDI)±1 (AX)-((DI或EDI)),(DI或EDI)-(DI或EDI)±2 (EAX)-((DI或EDI)),(DI或EDI)-(DI或EDI)±4 条件设置:指定条件cc满足则(r8/m8)送1,否则送0 保存全局描述符表寄存器:(mem)←(GDTR) 逻辑左移 SHLD reg/mem, reg, 双精度左移 I8自386起 386起 SHRD reg/mem, reg, 双精度右移 保存中断描述符表:(mem)←(IDTR) 保存局部描述符表:(reg/mem)←(LDTR) 保存机器状态字:(reg/mem)←(MSW) 进位位置1 方向标志置1 中断标志置1 ((DI或EDI))←(ac),(DI或EDI)←(DI或EDI)±1 ((DI或EDI))←(ac),(DI或EDI)←(DI或EDI)±2 ((DI或EDI))←(ac),(DI或EDI)←(DI或EDI)±4 保存任务寄存器:(reg/mem)←(TR) reg, (dst)←(dst)←(src) 286起,系统指令 286起,系统指令 286起,系统指令 386起 286起,系统指令 reg, (dst)∧(src),结果影响标志位 mem/imm/reg mem, reg/imm ac, imm VERR reg/mem VERW reg/mem WAIT WBINVD 检验reg/mem中的选择器所表示的段是否可读 检验reg/mem中的选择器所表示的段是否可写 等待 写回并使高速缓存无效 286起,系统指令 286起,系统指令 486起,系统指令 27

助 记 符 WRMSR XADD reg/mem, reg XCHG reg/ac/mem, reg XLAT XOR mem/imm/reg mem, reg/imm ac, imm 功 能 写入模型专用寄存器:MSR(ECX)←(EDX, EAX) TEMP←(src)+(dst), (src)←(dst), (dst)←TEMP (dst)← →(src) (AL)←((BX或EBX)+(AL)) reg, (dst)←(dst)⊕(src) 备 注 586起,系统指令 486起

3. MMX指令 指令类型 算术运算 PADD[B, W, D] PADDS[B, W] PADDUS[B, W] PSUB[B, W, D] PSUBS[B, W] PSUBUS[B, W] PMULHW PMULLW PMADDWD 比较 PCMPEQ[B, W, D] PCMPGT[B, W, D] 类型转换 PACKUSWB PACKSS[WB, DW] PUNPCKH[BW,WD,DQ] PUNPCKL[BW,WD,DQ] 逻辑运算 PAND PANDN POR PXOR 移位 PSLL[W, D, Q] PSRL[W, D, Q] PSRA[W, D] 数据传送 MOVD MOVD 助 记 符 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, m64/mm/I8 mm, m64/mm/I8 mm, m64/mm/I8 mm, r32/m32 r32/m32, mm 功 能 环绕加[字节,字,双字] 有符号饱和加[字节,字] 无符号饱和加[字节,字] 环绕减[字节,字,双字] 有符号饱和减[字节,字] 无符号饱和减[字节,字] 紧缩字乘后取高位 紧缩字乘后取低位 紧缩字乘,积相加 紧缩比较是否相等[字节,字,双字] 紧缩比较是否大于[字节,字,双字] 按无符号饱和压缩[字压缩成字节] 按有符号饱和压缩[字/双字压缩成字节/字] 扩展高位[字节/字/双字扩展成字/双字/4字] 扩展低位[字节/字/双字扩展成字/双字/4字] 紧缩逻辑与 紧缩逻辑与非 紧缩逻辑或 紧缩逻辑异或 紧缩逻辑左移[字,双字,4字] 紧缩逻辑右移[字,双字,4字] 紧缩算术右移[字,双字] 将r32/m32送MMX寄存器低32位,高32位清零 将MMX寄存器低32位送r32/m32 28

MOVQ MOVQ 状态清除 EMMS m64/mm, mm mm, m64/mm (m64/mm)←(mm) (mm)←(m64/mm) 清除MMX状态(浮点数据寄存器清空)

4. SSE指令 指令类型 转换指令 CVTPI2PS CVTPS2PI CVTPI2SS CVTSS2PI 浮点 数据传送 MOVAPS MOVAPS MOVUPS MOVUPS MOVHPS MOVHPS MOVLPS MOVLPS MOVHLPS MOVLHPS MOVMSKPS MOVSS MOVSS 组合指令 SHUFPS UNPCKHPS UNPCKHPS 浮点 比较运算 CMPPS CMPddPS CMPSS 指令助记符 xmm, mm/m64 mm, xmm/m64 xmm, r32/m32 r32, xmm/m32 xmm, xmm/m128 xmm/m128, xmm xmm, xmm/m128 xmm/m128, xmm xmm, m64 m64, xmm xmm, m64 m64, xmm xmm, xmm xmm, xmm r32, xmm xmm, m32 xmm/m32, xmm xmm,xmm/m128,I8 xmm,xmm/m128 xmm,xmm/m128 xmm,xmm/m128,I8 xmm,xmm/m128 xmm,xmm/m128,I8 功 能 紧缩整数转换为浮点数:将mm/m64中两个32位有符号整数转换为浮点数存入xmm低64位,高64位不变 紧缩浮点数转换为整数:将xmm低64位或m64中两个32位浮点数转换为两个32位有符号整数存入mmx寄存器 标量整数转换为浮点数:将r32/m32中32位有符号整数转换为浮点数存入xmm低32位,高96位不变 标量浮点数转换为整数:将xmm低32位或m32中32位浮点数转换为32位有符号整数存入r32 对齐数据传送:(xmm) ←(xmm/m128) 对齐数据传送:(xmm/m128) ←(xmm) 不对齐数据传送:(xmm) ←(xmm/m128) 不对齐数据传送:(xmm/m128) ←(xmm) 高64位传送:xmm高64位←(m64) 高64位传送:m64←(xmm高64位) 低64位传送:xmm低64位←(m64) 低64位传送:m64←(xmm低64位) 64位高送低:(xmm低64位) ←(xmm高64位) 64位低送高:(xmm高64位) ←(xmm低64位) 屏蔽位传送:将xmm中4个单精度浮点数符号位送r32低4位,其余位清零 标量数据传送:m32送xmm低32位,其余96位清零 标量数据传送:xmm低32位送m32/xmm低31位,其余96位不变 紧缩浮点数组合:将目的xmm4个单精度浮点数组合到目的xmm低两个浮点数位置,源操作数4个单精度浮点数进行组合送目的xmm高两个浮点数位置,组合方法由18决定 高交叉组合:将xmm/m128和xmm的高两个浮点数交叉组合到xmm 低交叉组合:将xmm/m128和xmm的低两个浮点数交叉组合到xmm 紧缩浮点数比较:xmm和xmm/m128中4对浮点数比较,如果满足I8或dd要求,xmm置全“1”,否则置全“0” dd为:EQ, LT, LE, UNORD, NEQ, NLT, NLE, ORD 对应I8为:0~7 标量浮点数比较:xmm和xmm/m128中最低一对浮点数比较,如果满足I8要求,xmm置全“1”,否则置全“0”

29

指令类型 浮点 比较运算 COMISS UCOMISS 指令助记符 xmm, xmm/m32 xmm, xmm/m32 功 能 设置整数标志有序标量浮点数比较:比较xmm和m32或xmm中最低一对浮点数,设置EFLAGS寄存器。源操作数是SnaN或QnaN时产生无效数值异常 设置整数标志无序标量浮点数比较:比较xmm和m32或xmm中最低一对浮点数,设置EFLAGS寄存器。源操作数是SnaN时产生无效数值异常 转换指令 CVTPl2PS CVTPS2P CVTPl2SS CVTSS2PI xmm, mm/m64 mm, xmm/m64 xmm, r32/m32 r32, xmm/m32 xmm, xmm/m128 xmm, xmm/m32 xmm, xmm/m128 xmm, xmm/m32 xmm, xmm/m128 xmm, xmm/m32 xmm, xmm/m128 xmm, xmm/m32 xmm, xmm/m128 xmm, xmm/m32 xmm, xmm/m128 xmm, xmm/m32 xmm, xmm/m128 xmm, xmm/m32 xmm, xmm/m128 xmm, xmm/m128 xmm, xmm/m128 xmm, xmm/m128 mm, mm/m64 r32, mm, I8 紧缩整数转换为浮点数:将mm/m64中两个32位有符号整数转换为浮点数存入xmm低64位,高64位不变 紧缩浮点数转换为整数:将xmm低64位或m64中两个32位浮点数转换为两个32位有符号整数存入mmx寄存器 标量整数转换为浮点数:将r32/m32中32位有符号整数转换为浮点数存入xmm低32位,高96位不变 标量浮点数转换为整数:将xm低32位或m32中32位浮点数转换为32位有符号整数存入r32 浮点 算术运算 ADDPS ADDSS SUBPS SUBSS MULPS MULSS DIVPS DIVSS SQRTPS SQRTPS MAXPS MAXSS MINPS MINSS 紧缩浮点数加:xmm和xmm/m128中四对浮点数加 标量浮点数加:xmm和xmm/m32中最低一对浮点数加 紧缩浮点数减:xmm和xmm/m128中四对浮点数减 标量浮点数减:xmm和xmm/m32中最低一对浮点数减 紧缩浮点数乘:xmm和xmm/m128中四对浮点数乘 标量浮点数乘:xmm和xmm/m32中最低一对浮点数乘 紧缩浮点数除:xmm和xmm/m128中四对浮点数除 标量浮点数除:xmm和xmm/m32中最低一对浮点数除 紧缩浮点数平方根:求xmm/m128中四对浮点数平方根,存入xmm 标量浮点数平方根:求xmm/m32中最低一对浮点数平方根,存入xmm低32位,高96位不变 紧缩浮点数最大值:求xmm/m128和xmm中四对浮点数最大值,存入xmm 标量浮点数最大值:求xmm/m32和xmm中最低一对浮点数最大值,存入xmm低32位,高96位不变 紧缩浮点数最小值:求xmm/m128和xmm中四对浮点数最小值,存入xmm 标量浮点数最小值:求xmm/m32和xmm中最低一对浮点数最小值,存入xmm低32位,高96位不变 逻辑与:实现两个128位操作数按位逻辑与 逻辑非与:对128位目的操作数求反,然后与源操作数按位逻辑与 逻辑或:实现两个128位操作数按位逻辑或逻辑异或:实现两个128位操作数按位逻辑异或 紧缩整数求平均值:按字节/字求对应两个无符号数平均值 取出字:将mm中18低两位指定的16位字送r32低16位,高位清零 30

逻辑运算 指令 ANDPS ANDNPS ORPS XORPS 整数指令 PAVG[B,W] PEXTRW

指令类型 PINSRW PMAXUB 整数指令 PMAXSW PMINUB PMINSW 指令助记符 mm, r32/m16, I8 mm, mm/m64 mm, mm/m64 mm, mm/m64 mm, mm/m64 r32, mm mm, mm/m64 mm, mm/m64 mm, mm/m64, I8 m32 m32 m512 m512 mm, mm m64, mm m128, xmm m8 功 能 插入字:将m16或r32中低16位字送mm中由18指定的16位字 紧缩整数求最大值:按字节求对应8对无符号数最大值存入mm 紧缩整数求最大值:按字求对应4对有符号数最大值存入mm 紧缩整数求最小值:按字节求对应8对无符号数最小值存入mm 紧缩整数求最小值:按字求刑应4对有符号数最小值存入mm 屏蔽位传送:将mm寄存器每个字节最高位送r32的最低8位,高位清零 无符号高乘:进行4对无符号整数乘法,积的高16位送mm寄存器 绝对差求和:求8对有符号数差的绝对值,它们的和送mm的低16位 紧缩整数组合:按照18给出的方式,把两个紧缩字整数组合到mm中 PMOVMSKB PMULHUW PSADBW PSHUFW 状态管理 指令 STMXCSR LDMXCSR FXSAVE FXRSTOR 高速缓存 优化处理 指令 MASKMOVQ MOVNTQ MOVNTPS PREFETCH [T0,T1,T2,NTA] SFENCE 保存SIMD控制/状态寄存器:将SIMD控制/状态寄存器内容装入m32 恢复SIMD控制/状态寄存器:将m32内容装入SIMD控制/状态寄存器 保存所有状态:将FPU,MMX和SIMD所有状态装入m512 恢复所有状态:从m512恢复FPU,MMX和SIMD所有状态 字节屏蔽写入:将目的mm寄存器内容按源mm寄存器8字节最高位屏蔽后(等于1,数据不变;等于0,数据清零)送DS:DI/EDI指定的存储单元。数据不经过Cache 64位传送:将mm寄存器内容不经过Cache写入m64存储器 紧缩浮点数传送:将xmm寄存器内容不经过Cache写入m128存储器 预取:将m8指定的Cache行组内容预取进入由T0, T1, T2, NTA规定的各级Cache T0——预取数据进入各级Cache T1——预取数据进入除第一级以外的各级Cache T2——预取数据进入除第一级、第二级以外的各级Cache TA——仅将预取数据进入第一级Cache 存储隔离:保证在执行本指令之前的写入指令对本指令后的写入指令可见,避免预取指令的副作用

31

附录D 伪指令和操作符

1. 伪指令

伪指令类型 变量定义 伪 指 令 DB/BYTE/SBYTE, DW/WORD/SWORD, DD/DWORD/SDWORD/REAL4, FWORD/DF, QWORD/DQ/REAL8, TBYTE/DT/REAL10 定位 符号定义 简化段定义 完整段定义 复杂数据类型 流程控制 过程定义 宏汇编 重复汇编 条件汇编 模块化 条件错误 列表控制 EVEN, ALIGN, ORG RADIX, =, EQU, TEXTEQU, LABEL .MODEL, .STARTUP, .EXIT, .STACK, .DATA?, .CONST, .FARDATA, .FARDATA? SEGMENT, ENDS, GROUP, ASSUME, END, .DOSSEG/.ALPHA/.SEQ STRUCT/STRUC, UNION, RECORD, TYPEDER, ENDS .IF, .ELSE, .ELSEIF, .ENDIF, .WHILE, .ENDW, .REPEAT, .UNTIL, . BREAK, .CONTINUE PROC, ENDP, PROTO, INVOKE MACRO, ENDM, PURGE, LOCAL, PUSHCONTEXT, POPCONTEXT, EXITM, GOTO REPEAT/REPT, WHILE, FOR/IRP, FORC/IRPC IF, IFE, IFB, IFNB, IFDEF, IFNDEF, IFDIF, IFIDN, ELSE, ELSEIF, ENDIF PUBLIC, EXETEN/EXTERN, COMM, INCLUDE, INCLUDELIB .ERR, . ERRE, .ERRB, . ERRNB, .ERRDEF, .ERRNDEF, .ERRDIF, . ERRIDN TITLE, SUBTITLE, PAGE, .LIST, .LISTALL, . LISTMACRO, .LISTMACROALL, .LISTIF, .NOLIST, .TFCOND, .CREF, .NOCREF, COMMENT, ECHO 处理器选择 字符串处理 .8086, .186, .286, .286P, .386, .386P, 486, .486P, .8087, .287, .387, .NO87 CATSTR, INSTR, SIZESTR, SUBSTR 2. 操作符

操作符类型 算术运算符 逻辑运算符 移位运算符 关系运算符 高低分离符 地址操作符 类型操作符 复杂数据操作符 宏操作符 流程条件操作符 +, -, *, /, MOD AND, OR, XOR, NOT SHL, SHR EQ, NE, GT, LT, GE, LE HIGH, LOW, HIGHWORD, LOWWORD [ ], $, ;, OFFSET, SEG PTR, THIS, SHORT, TYPE, SIZEOF/SIZE, LENGTHOF/LENGTH ( ), < >, ., MASK, WIDTH, ?, DUP, “/” &, < >, !, %, ;; = =, !=, >, >=, <, <=, &&, ||, !, &, CARRY?, OVERFLOW? PARITY?, SIGN, ZERO? 操 作 符

32

附录E DOS功能调用

AH 00 01 02 03 04 05 06 功 能 程序终止(同INT21H) 键盘输入并回显 显示输出 辅助设备(COM1)输入 辅助设备(COM1)输出 打印机输出 直接控制台I/O 调用参数 CS=程序段前缀PSP DE=输出字符 DL=输出字符 DE=输出字符 DL=FF(输入) DE=字符(输出) 07 08 键盘输入(无回显) 键盘输入(无回显) 检测Ctrl+Break或Ctrl+C 09 显示字符串 DS:DX=串地址(字符串以?$?结尾) 0A 键盘输入到缓冲区 DS:DX=缓冲区首址 (DS:DX)=缓冲区最大字符数 0B 检验键盘状态 AL=00有输入 AL=FF无输入 0C 清除缓冲区并请求 指定的输入功能 0D 0E 0F 磁盘复位 指定当前默认的磁盘驱动器 打开文件(FCB) DL=驱动器号(0=A,1=b, …) DS:DX=FCB首地址 清除文件缓冲区 AL=系统中驱动器数 AL=00文件找到 AL=FF文件未找到 10 关闭文件(FCB) DS:DX=FCB首地址 AL=00目录修改成功 AL=FF目录中未找到文件 11 查找第一个目录项(FCB) DS:DX=FCB首地址 AL=00找到匹配的目录项 AL=FF未找到匹配的目录项 12 查找下一个目录项(FCB) DS:DX=FCB首地址 使用通配符进行目录项查找 13 删除文件(FCB) DS:DX=FCB首地址 AL=00找到匹配的目录项 AL=FF未找到匹配的目录项 AL=00删除成功 AL=FF文件未删除 14 顺序读文件(FCB) DS:DX=FCB首地址 AL=00读成功 =01文件结束,未读到数据 =02DTA边界错误 =03文件结束,记录不完整 AL=输入功能号(1,6,7,8) AL=输入字符 (DS:DX+1)=实际输入的字符数 AL=输入字符 AL=输入字符 AL=输入字符 AL=输人数据 AL=输入字符 返回参数 33

AH 15 功 能 顺序写文件(FCB) 调用参数 DS:DX=FCB首地址 返回参数 AL=00写成功 =01磁盘满或是只读文件 =02DTA边界错误 16 建文件(FCB) DS:DX=FCB首地址 AL=00建文件成功 =FF磁盘操作有错 17 文件改名(FCB) DS:DX=FCB首地址 AE=00文件被改名 =FF文件未改名 19 取当前默认磁盘驱动器 AL=默认的驱动器号 0=A,1=B,2=C,... 1A 1B 设置DTA地址 取默认驱动器FAT信息 DS:DX=DTA地址 AL=每簇的扇区数 DS:BX=指向介质说明的指针 CX=物理扇区的字节数 DX=每磁盘簇数 1C 1F 取指定驱动器FAT信息 取默认磁盘参数块 DL=驱动器号 同上 AL=00无错 =FF出错 DS:BX=磁盘参数块地址 21 随机读文件(FCB) DS:DX=FCB首地址 AL=00读成功 =01文件结束 =02 DTA边界错误 =03读部分记录 22 随机写文件(FCB) DS:DX=FCB首地址 AL=00写成功 =01磁盘满或是只读文件 =02 DTA边界错误 23 测定文件大小(FCB) DS:DX=FCB首地址 AL=00成功,记录数填入FCB =FF未找到匹配的文件 24 25 设置随机记录号 设置中断向量 DS:DX=FCB首地址 DS:DX=中断向量 AL=中断类型号 26 27 建立程序段前缀PSP 随机分块读(FCB) DX=新PSP段地址 DS:DX=FCB首地址 CX=记录数 AL=00读成功 =01文件结束 =02 DTA边界错误 =03读部分记录 CX=读取的记录数 28 随机分块写(FCB) DS:DX=FCB首地址 CX=记录数 AL=00写成功 =01磁盘满或是只读文件 =02 DTA边界错误 34

AH 29 功 能 分析文件名字符串(FCB) 调用参数 ES:DI=FCB首址 DS:SI=ASCIZ串 AL=分析控制标志 返回参数 AL=00标准文件 =01多义文件 =FF驱动器说明无效 CX=年(1980~2099) DH=月(1~12) DL=日(1~31) AL=星期(0~6) 2A 取系统日期 2B 置系统日期 CX=年(1980~2099) DH=月(1~12) DL=日(1~31) AL=00成功 =FF无效 2C 取系统时间 CH:CL=时:分 DH:DL=秒:1/100秒 2D 置系统时间 CH:CL=时:分 DH:DL=秒:1/100秒 AL=00成功 =FF无效 2E 设置磁盘检验标志 AL=00关闭检验 =FF打开检验 2F 30 取DTA地址 取DOS版本号 ES:BX=DTA首地址 AL=版本号 AH=发行号 BH=DOS版本标志 BL:CX=序号(24位) 31 结束并驻留 AL=返回码 DX=驻留区大小 32 取驱动器参数块 DL=驱动器号 AL=FF驱动器无效 DS:BX=驱动器参数块地址 33 Ctrl+Break检测 AL=00取标志状态 DL=00关闭Ctrt-Break检测 =01打开Ctrl-Break检测 35 36 取中断向量 取空闲磁盘空间 AL=中断类型 DL=驱动器号 0=默认,1=A,2=B,… ES:BX=中断向量 成功:AX=每簇扇区数 BX=可用簇数 CX=每扇区字节数 DX=磁盘总簇数 38 置/取国别信息 AL=00取当前国别信息 =FF国别代码放在BX中 DS:DX=信息区首地址 DX=FFFF设置国别代码 BX=国别代码 (国际电话前缀码) DS:DX=返回的信息区首址 AX=错误代码 AX=错误码 AX=错误码 39 3A 建立子目录 删除子目录 DS:DX=ASCIZ串地址 DS:DX=ASCIZ串地址 35

AH 3B 3C 功 能 设置当前目录 建立文件(handle) 调用参数 DS:DX=ASCIZ串地址 DS:DX=ASCIZ串地址 CX=文件属性 AX=错误码 返回参数 成功:AX=文件代号(CF=0) 失败:AX=错误码 (CF=1) 成功:AX=文件代号(CF=0) 失败:AX=错误码(CF=1) 3D 打开文件(handle) DS:DX=ASCIZ串地址 AL=访问和文件共享方式 0=读,1=写,2=读/写 3E 3F 关闭文件(handle) 读文件或设备(handle) BX=文件代号 DS:DX=ASCIZ串地址 BX=文件代号 CX=读取的字节数 失败:AX=错误码 (CF=1) 成功:AX=实际读入的字节数(CF=0) AX=0已到文件尾 失败:AX=错误码(CF=1) 成功:AX=实际写入的字节数 失败:AX=错误码(CF=1) 40 写文件或设备(handle) DS:DX=ASCIZ串地址 BX=文件代号 CX=写入的字节数 41 删除文件 DS:DX=ASCIZ串地址 成功:AX=00 失败:AX=错误码(CF=1) 42 移动文件指针 BX=文件代号 CX:DX=位移量 AL=移动方式 成功:DX:AX=新指针位置 失败:AX=错误码(CF=) 43 置/取文件属性 DS:DX=ASCIZ串地址 AL=00取文件属性 AL=01置文件属性 CX=文件属性 成功:CX=文件属性 失败:AX=错误码(CF=1) 44 设备驱动程序控制 BX=文件代号 AL=设备子功能代码(0~11H) 0=取设备信息 1=置设备信息 成功:DX=设备信息 AX=传送的字节数 失败:AX=错误码 (CF=1) 44 设备驱动程序控制 2=读字符设备 3=写字符设备 4=读块设备 5=写块设备 6=取输入状态 7=取输出状态 BL=驱动器代码 CX=读/写的字节数 45 复制文件代号 BX=文件代号1 成功:AX=文件代号2 失败:AX=错误码(CF=1) 46 强行复制文件代号 BX=文件代号1 CX=文件代号2 失败:AX=错误码(CF=1) 47 取当前目录路径名 DL=驱动器号 DS:SI=ASCIZ串地址 (从根目录开始的路径名) 成功:DS:SI=当前ASCIZ串地址 失败:AX=错误码(CF=1) 36

AH 48 功 能 分配内存空间 调用参数 BX=申请内存数 返回参数 成功:AX=分配内存的初始段地址 失败:AX=错误码(CF=1) BX=最大可用空间 49 4A 释放已分配内存 修改内存分配 ES=内存起始段地址 ES=原内存起始段地址 BX=新申请内存字节数 失败:AX=错误码(CF=1) 失败:AX=错误码(CF=1) BX=最大可用空间 失败:AX=错误码 4B 装入/执行程序 DS:DX=ASCIZ串地址 ES:BX=参数区首地址 AL=00装入并执行程序 =03装入程序,但不执行 4C 4D 带返回码终止 取返回代码 AL=返回码 AL=子出口代码 AH=返回代码 00=正常终止 01=用Ctrl+C终止 02=严重设备错误终止 03=用功能调用31H终止 4E 查找第一个匹配文件 DS:DX=ASCIZ串地址 CX=属性 失败:AX=错误码 (CF=1) 4F 50 51 52 53 查找下一个匹配文件 置PSP段地址 取PSP段地址 取磁盘参数块 把BIOS参数块(BPB)转换为 DOS的驱动器参数块(DPB) DTA保留4EH的原始信息 BX=新PSP段地址 DS:SI=BPB的指针 ES:BP=DPB的指针 失败:AX=错误码(CF=1) BX=当前运行进程的PSP ES:BX=参数块链表指针 54 取写盘后读盘的检验标志 AL=00检验关闭 =01检验打开 55 56 建立PSP 文件改名 DX=建立PSP的段地址 DS:DX=当前ASCIZ串地址 ES:DI=新ASCn串地址 失败:AX=错误码 (CF=1) 57 置/取文件日期和时间 BX=文件代号 AL=00读取日期和时间 AL=01设置日期和时间 (DX:CX)=日期,时间 失败:AX=错误码 (CF=1) 58 取/置内存分配策略 AL=00取策略代码 AL=01置策略代码 BX=策略代码 成功:AX=策略代码 失败:AX=错误码 (CFM) 37

AH 59 功 能 取扩充错误码 BX=00 调用参数 返回参数 AX=扩充错误码 BH=错误类型 BL=建议的操作 CH=出错设备代码 5A 建立临时文件 CX=文件属性 DS:DX=ASCIZ串(以\\结束) 地址 成功:AX=文件代号 DS:DX=ASCIZ串地址 失败:AX=错误代码 (CF=1) 成功:AX=文件代号 失败:AX=错误代码 (CF=1) 失败:AX=错误代码 (CF=1) 5B 建立新文件 CX=文件属性 DS:DX=ASCIZ串地址 5C 锁定文件存取 AL=00锁定文件指定的区域 =01开锁 BX=文件代号 CX:DX=文件区域偏移值 SI:DI=文件区域的长度 5D 取/置严重错误标志的地址 AL=06取严重错误标志地址 AL=0A置ERROR结构指针 DS:SI=严重错误标志的地址 60 扩展为全路径名 DS:SI=ASCIZ串的地址 ES:DI=工作缓冲区地址 失败:AX=错误代码(CF=1) 62 68 6C 取程序段前缀地址 刷新缓冲区数据到磁盘 扩充的文件打开/建立 AL=文件代号 AL=访问权限 BX=打开方式 CX=文件属性 DS:SI=ASCIZ串地址 BX=PSP地址 失败:AX=错误代码(CF=1) 成功:AX=文件代号 CX=采取的动作 失败:AX=错误代码(CF=1)

38

附录F BIOS功能调用

INT AH 功 能 调用参数 AL=00 40x25黑白文本,16级灰度 =01 40x25 16色文本 10 0 设置显示方式 =02 80x25黑白文本,16级灰度 =03 80x25 16色文本 =04 320x200 4色图形 =05 320x200黑白图形,4级灰度 =06 640x200黑白图形 =07 80x25黑白文本 =08 160x200 16色图形(MCGA) =09 320x200 16色图形(MCGA) =0A 640x200 4色图形(MCGA) 10 0 设置显示方式 =0D 320x200 16色图形(EGA/VGA) =0E 640x200 16色图形(EGA/VGA) =0F 640x350单色图形(EGA/VGA) =10 640x350 16色图形(EGA/VGA) =11 640x480黑白图形(VGA) =12 640x480 16色图形(VGA) =13 320x200 256色图形(VGA) 10 10 1 2 置光标类型 置光标位置 (CH)0~3=光标起始行 (CL)0~3=光标结束行 BH=页号 DH/DL=行/列 BH=页号 10 3 读光标位置 10 4 读光笔位置 CH=光标起始行 CL=光标结束行 DH/DL=行/列 AX=0光笔未触发 =1光笔触发 CH/BX=像素行/列 DH/DL=字符行/列 10 5 置当前显示页 AL=页号 AL=0初始化窗口 AL=上卷行数 10 6 屏幕初始化或上卷 BH=卷入行属性 CH/CL=左上角行/列号 DH/DL=右下角行/列号 AL=0初始化窗口 AL=下卷行数 10 7 屏幕初始化或下卷 BH=卷入行属性 CH/CL=左上角行/列号 DH/DL=右下角行/列号

39

返回参数 INT AH 10 8 功 能 读光标位置的字符和属性 在光标位置显示字符和 属性 BH=显示页 BH=显示页 调用参数 返回参数 AH/AL=属性/字符 10 9 AL/BL=字符/属性 CX=字符重复次数 BH=显示页 AL=字符 CX=字符重复次数 BH=彩色调色板ID BL=和ID配套使用的颜色 AL=颜色值 BH=页号 DX/CX=像素行/列 BH=页号 DX/CX=像素行/列 AL=字符 BH=页号 BL=前景色 BH=页号 AH=字符列数 AL=显示方式 AL=0,BL=调色板号,BH=颜色值 AL=0~4全部或部分装入字符点阵集 AL=20~24置图形方式显示字符集 AL=30读当前字符集信息 BL=10H(子功能) BH=0单色方式 =1彩色方式 BL=VRAM容量 (0=64KB,1=128KB,…) CH=特征位设置 CL=EGA的开关设置 ES:BP=字符串地址 AL=写方式(0~3) ES:BP=字符集位置 AL=像素的颜色值 10 A 在光标位置显示字符 10 B 置彩色调色板 10 C 写像素 10 D 读像素 显示字符 (光标前移) 10 E 10 F 取当前显示方式 置调色板寄存器(EGA/VGA) 装入字符发生器 (EGA/VGA) 10 10 10 11 10 12 返回当前适配器设置的 信息(EGA/VGA) 10 13 显示字符串 CX=字符串长度 DH/DL=起始行/列 BH/BL=页号/属性 AX=返回值(位映像) 0=对应设备未安装 1=对应设备已安装 DL=驱动器号 AX=内存容量(单位KB) 失败:AH=错误码 11 12 13 0 取系统设备信息 取内存容量 磁盘复位 40

顺序,将不会产生这种错误。

18 Operand must be register:operand,操作数应当是寄存器,但却是一个符号或常量。 20 Operand must be segment or group,操作数应当是段名或组名。提供的却是其他名字或常数。

22 Operand must be type specifier,操作数应当是类型说明符。如NEAR或WORD,但给出的是其他操作数。

23 Symbol already defined locally,在当前模块中已定义的符号又说明为EXTERN的操作数。

24 Segment parameters are changed,同名段操作数说明有矛盾。语句要求应相同。 25 Improper align/combine type,SEGMENT语句操作数错,检查定位和组合类型。 26 Reference to multidefined symbol,引用多重定义的符号。 27 Operand expected,需要一个操作数,但接收到的是操作符。 28 Operator expected,需要一个操作符,但给的却是操作数。 29 Division by 0 or overflow,表达式结果被零除或结果溢出。

30 Negative shift count,作为SHL/SHR的操作数的表达式计算成一个负的移位次数。 31 Operand types must match,操作数类型应当匹配。如DATA是字节变量,则语句“MOVAX,DATA”会产生这个错误。为消除该错误,上述语句应改为“MOV AX,WORD PTR DATA”。

32 Illegal use of external,外部变量使用不正确。

34 Operand must be record or field name,要求操作数是记录或域名。

35 Operand must have size,要求操作数有指定的尺寸。如语句INC[BX]将产生这个错误。

38 Left operand must have segment,段取代前缀必须是段寄存器、组或段名。 39 One operand must be constant,应当有一个常数操作数。

40 Operands must be in the same segment,or one must be constant,操作数应在同一段或应有一个常数。

42 Constant expected,希望一个常数。

43 Operand must have segment,操作数应当有段。

44 Must be associated with data,要求数据相关项的地方用了与代码相关的项。 45 Must be associated with code,要求代码相关项的地方用了数据相关的项。 46 Multiple base registers,操作数中使用了多今基址寄存器。如语句“MOV AX,[BX+BP]”非法。

47 Multiple index registers,操作数中使用了多个变址寄存器。如语句“MOV AX,[SI+DI]非法。

48 Must be index or base registers,存储器操作数要求是基址或变址寄存器,但给的是其他寄存器。

49 Illegal use of registers,寄存器的使用非法。

50 Value out of range,值超出范围。如语句“MOV AL,5000”是非法的,因字节寄存

46

器应使用字节值。

51 Operand not in current CS ASSUME segment,操作数超出ASSUME语句分配的代码范围。通常是对标号的调用或转移超出当前代码段。

52 Improper operand type:symbol,非法的操作数类型。如语句“MOV mem1,mem2”非法,原因是两个均为存储器操作数。

53 Jump out of range by number bytes,条件转移指令不在要求的范围之内。

55 Illegal register value,非法使用寄存器。如语句“MOV AX,BP+4”非法,正确语句为“MOVAX,[BP+4]”。

56 Immediate mode illegal,立即操作数非法。如语句“MOVDS,1000H”的立即操作数非法。

57 Illegal size for operand,特定语句的操作数非法。如INC MEM32,MEM32为双字变量。

58 Byte register illegal,8位寄存器用在要求16位寄存器的语句中。如PUSHAL非法。 59 Illegal use of CS register,非法使用CS。如语句“POPCS”非法。

60 Must be accumulator register,在应使用AL、AX的语句中使用了其他寄存器。 61 Improper use of segment register,段寄存器使用非法。如语句INCCS。

62 Missing or unreachable code segment,企图转移到MASM不能识别为代码段的标号。通常是因为无ASSUME语句使CS与代码段相连造成的。 63 Operand combination illegal,操作数组合非法。

64 Near JAMP/CALL to different code segment,近程调用和跳转语句企图转移到非当前代码段。

65 Label cannot have segment override,标号不允许有段前缀,即段取代前缀使用有误。 66 Must have instruction after prefix,前缀后应当有指令。

67 Cannot override ES for destination,段取代前缀ES不能用在串操作指令的目的操作数上。

68 Cannot address with segment register,企图访问存储操作数,但没有用ASSUME说明该操作数所在的段。请使用段取代或ASSUME标示出该操作数的属性。 69 Must be in segment block,应在段内使用的伪指令用在了段外。

70 Cannot use EVEN or ALIGN with type,EVEN和ALIGN伪指令用在字节对准的段内。 71 Forward reference needs override or FAR,调用或转移语句提前引用其他段的标号需使用PTR操作符予以说明。如CALL FAR PTR TASK,引用标号TASK时还未定义TASK标号。

72 Illegal value for DUP count,重复子句的数值表达式不为正整数值。 73 Symbol is already external,已定义为外部名字的符号又被定义为内部名字。 74 DUP nesting too deep,重复子句嵌套超过17层。

75 Illegal use of undefined operand(?),“?”使用不正确。如“MOV AH,?”和“5 DUP(?+5)”均非法。

76 Too many values for structure or ecord initialization,初始化结构或记录变量时给出过

47

多初始值。

77 Angle brackets required around initialized list,初始化结构变量时,没有使用尖括号括起初始值。

78 Directive illegal in structure,结构定义中的语句非法。

79 Override with DUP illegal,初始化结构变量时,使用了重复子句DUP。 80 Field cannot be overridden,初始化结构变量时,企图预置不能被预置的域。 83 Circular chain of EQU aliases,用EQU伪指令定义的符号名指向自身。如语句“A EQU B”和“B EQU A”非法,将产生该错误。

84 Cannot emulate coprocessor or opcode,协处理器指令或操作数与产生协处理器仿真程序不支持的操作码一起使用。

85 End of file,no END directive。源程序无END语句。该错误也可能在段嵌套出错时产生。

86 Data emitted with no segment,应在段内使用的语句在段外使用。产生目标代码的语句必须在段内,不产生目标代码的语句可在段内,也可在段外。 87 Forced error-passl,用.ERR1伪指令强制形成的错误。 88 Forced error-pass2,用.ERR2伪指令强制形成的错误。 89 Forced error,用.ERR伪指令强制形成的错误。

90 Forced error-expression true(0),用.ERRZ伪指令强制形成的错误。 91 Forced error-expression false(not0),用.ERRZ伪指令强制形成的错误。 92 Forced error-symbol not defined,用.ERRNDEF伪指令强制形成的错误。 93 Forced error-symbol defined,用.ERRDEF伪指令强制形成的错误。 94 Forced error-string blank,用.ERRB伪指令强制形成的错误。 95 Forced error-string not blank,用.ERRNB伪指令强制形成的错误。 96 Forced error-strings identical,用.ERRIDN伪指令强制形成的错误。 97 Forced error-strings different,用.ERRDIF伪指令强制形成的错误。

98 Wrong length for override value,结构域的重设值太大以至不适宜于这个域。 99 Line too long expanding symbol:symbol,使用EQU伪指令定义的等式太长。 101 Missing data;zero assumed,缺少操作数,假定是零。

103 Align must be power of2,ALIGN伪指令用了不是2的幂的参数。

104 Jump within short distance,JMP指令的转移范围在短标号内,故可在标号前加SHORT操作符,从而使指令代码减少一个字节。

105 Expected element,少了一个元素,如标点符号或操作符。

106 Line too long,源行超过MASM允许的最大长度。MASM5.0规定行长为128个字符。

107 Illegal digit in number,常数内包含当前的基不允许的数字,如108Q。 108 Empty string not allowed,空串不允许出现。如“NULLDB’’ ’’”语句非法。 109 Missing Operand,语句缺少一个必需的操作数。

110 Open parenthesis or bracket,语句中缺少一个圆括号或方括号。

48

111 Directive must be in macro,只在宏定义里面使用的伪指令用在宏定义之外。

112 Unexpected end of line,语句行不完整。

附录6.2 无编号的错误信息

无编号错误信息提示在命令行、存储器分配或文件访问中出现错误。 (1)命令行错误

MASM时,若用户给出无效命令行,将产生如下提示信息之一: Buffer size expected after B option

Error defining symbol ''name'' from command line Extra file name ignored Line invalid,start again Path expected after I option Unknown case option:option Unknown option:option (2)文件访问错误

当MASM处理文件时,若出现磁盘空间不够、错误文件名或其他文件错误,则将产生如下提示信息之一:

End of file encountered on input file Include file filename not found Read error on standard input Unable to access input file:filename Unable to open cref file:filename Unable to open input file:filename Unable to open listing file:filename Unable to open object file:filename Write error on cross-reference file Write error on listing file Write error on object file (3)其他错误

表示存储分配出错或其他一些与特定源程序的行不相关的汇编出错等提示信息。 Internal error,内部出错,注意错误发生时的情况。

Internal error-problem with expression analyzer分析表达式出现内部错误,说明表达式构成有误。

Internal unknown error,MASM不能识别的内部表有错。 Number of open conditionals:(number)有IF而没有ENDIF语句。 Open procedures,无与PROC匹配的ENDP语句。 Open segments,无与SEGMENT匹配的ENDS语句。

Out of memory,存储器有效空间用完,可能是源文件太长或符号表中定义了太多符号。

49

读下列程序,在空格处填上恰当语句,使其功能实现显示输出已定义的字符串。 DATA SEGMENT

STR DB ‘WELCOME’,’$’ DATA ENDS ;代码段

START: MOV AX, DATA MOV DS, AX L1: MOV DL,[BX] MOV AH,02H

INC BX

JNZ L1

HLT

50

本文来源:https://www.bwwdw.com/article/8w6a.html

Top