汇编语言程序设计课件_第1页
汇编语言程序设计课件_第2页
汇编语言程序设计课件_第3页
汇编语言程序设计课件_第4页
汇编语言程序设计课件_第5页
已阅读5页,还剩91页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

汇编语言程序设计一、汇编语言程序格式二、汇编语言程序设计基础三、直线程序四、分支程序五、循环程序六、码转换程序设计七、有关序列的操作八、DOS功能调用九、子程序设计一、汇编语言程序格式my_datasegmentagain:Moval,[si]array1db05,a2H,00,10H,85H

Incsinequ5

Cmpal,50array2dbndup(?)

Jbenextmy_dataends

Mov[di],almy_codesegment

Incdi

assumecs:my_codenext:deccx

assumeds:my_datajnzagainbegin:movax,my_datamovah,4chmovds,axint21hLeasi,array1

my_codeendsLeadi,array2endbeginMovcx,n05A2001085array1array2DSCS汇编语言基本构成:1.基本格式2.语句行构成标识符操作码操作数1[,操作数2];注释(1)8088汇编语句中的标记(3)表达式3.伪指令4.指令符号定义语句数据定义语句段定义语句过程定义语句程序开始结束语句(2)符号8088汇编语言的源程序是由多个段组成的,一个可执行的汇编程序一般至少有一个代码段,其中包含可执行的语句。其基本格式如图:1.基本格式S_NAME1SEGMENT

语句

语句S_NAME1ENDSS_NAME2SEGMENT

语句

语句S_NAME2ENDSS_NAME3SEGMENT

语句

语句S_NAME3ENDSEND2.语句行构成每个段是由语句行构成的。一个语句行的基本格式为:

标识符操作码操作数1[,操作数2];注释(1)8088汇编语句中的标记

1.标识符标识符由一串字符构成,用于一段程序、一组(或一个)数据或一个段的开头。使用时要注意以下3点:•

标识符可由数字、字母和下划线组成;•不能以数字开头,数据可用在非开头的其它位置;•

其最大长度为31个字符。2.保留字

保留字是汇编语言中预先保留的特殊字串,只能用于特殊用途,所有8086/8088的指令、伪指令和寄存器名都是保留字。如AX、MOV、DB、INT、EQU等等。

保留字不能用作标识符3.界符界符是用于一个程序或一条指令中不同部分的分隔符,如MOVAX,0010H中的“,”就是界符。其内容见下表:8086/8088汇编语言的界符’;><*,:[]+-=()$&?./4.常量常量就是指令中的一些不变的数据。它可以用二进制、十六进制、十进制和八进制表示,也可以用引号引起来的字串。例如:二进制:00011101B

十六进制:0C5AAH

十进制:9856D

八进制:237O

字串:’The2Xmeans2multipleX’

其中的B、H、D和O为数制的结尾符。

5.注释注释是用于使程序易于理解的句子,用来表示某行或某段语句的作用或与其它部分的关系,一般写在某语句的后面或某段的开始处,注释的前面由“;”前导,表示后面的内容为注释。如果一行写不下,换行后也要使用“;”前导。(2)符号

在8086/8088汇编语言的源程序中为了使程序有很好的可读性和易修改性,通常使用有一定意义的符号来代替某些单元、数据或表达式。符号可分为四类:寄存器、变量、标号、数。如SUM、DATA1。1.寄存器

8086/8088的寄存器是程序中最常出现的符号,它可分为字节寄存器和字寄存器,如AX为字寄存器,而AL则为字节寄存器。只有AX、BX、CX、DX可分为字和字节寄存器。2.变量

变量是存放在某些单元中的操作数,使用有一定意义的符号来代表这些单元。所有的变量都有一个固定的地址,它由段和偏移组成;同时还有一个类型,它可以是字节、字或双字。在程序中,变量可以使用数据定义伪指令进行初始化,见伪指令一节中的数据定义部分。3.标号标号实际上是用符号表示的地址,因此它也是由段、偏移地址和类型组成,其类型分为段内(NEAR)和段间(FAR)两种,通过

SEG

标号

OFFSET

标号可以分别得到标号的段地址和偏移地址。如果是NEAR类型,在程序执行时,只取标号的偏移地址,例如在过程调用(CALL)时,只取IP,而对于FAR类型,则要取段地址和偏移地址,在CALL时要取IP和CS。4.数在程序设计中,为了程序有良好的可读性和可修改性,有些数据使用符号来表示,通过伪操作,将数据与某些符号相联系。(3)表达式

表达式由操作数和运算符组成,如3+2、77AND55、NOT5AH等。1.操作数操作数用于代表一个数据或一个地址。2.运算符运算符包括算术、逻辑、关系、分析、综合五类运算符。

①算术运算符

包括+、-、*、/、MOD

参加运算的内容可以是数据,也可以是地址,但在一个算术运算符的两边不能都是地址。

②逻辑运算符

包括AND、OR、NOT、XOR③关系运算符

包括相等:EQ

大于:GT

不等:NE

小于或等于:LE

小于:LT

大于或等于:GE

关系运算结果只有两个——真、假。如果关系是真,则结果为0FFH(0FFFFH);如果关系是假,则结果为0。例如

MOVBX,DATA1LT0010H

MOVBX,0FFFFH

MOVBX,DATA1LT0010HMOVBX,0当DATA1<0010H时

当DATA1>0010H时

④分析运算符分析运算在汇编语言程序设计中很重要。它包括取存储单元偏移:OFFSET

取存储单元段:

SEG

取类型:TYPE

取字节数:

SIZE

按类型取长度:LENGTH例1:设有数据段中使用

DATA1DB?定义了一个单元,则

05A2001085DSCSDATA12000:1500①

MOVAL,DATA1

可将DATA1中的数传送到AL中,AL=05②

MOVAX,SEGDATA1可将DATA1的所在段地址传到AX中,AX=2000

MOVAX,OFFSETDATA1可将DATA1的偏移地址传入AX中,AX=1500例2:设有数据段中使用

DATA1DW100DUP(?)

定义了100个字单元,则

MOVAX,TYPEDATA1AX=2MOVAX,SIZEDATA1AX=200MOVAX,LENGTHDATA1AX=100⑤综合运算符综合运算符包括两个地址操作符PTR和THIS。

PRT——改变存储器地址操作数的操作类型,但其段地址和偏移地址不变。如:

DATA1DW100DUP(?)05A2001085DSMOVAL,DATA1MOVAL,BYTEPTRDATA1

√DATA1×DATA1SEGMENTWBUFFEREQUTHISWORDBUFFERDB12H,34H,00H,91HDATA1ENDSCODE1SEGMENTASSUMECS:CODE1,DS:DATA1START:MOVAX,DATA1MOVDS,AX

MOVAL,BUFFERMOVBX,WBUFFER

……CODE1ENDSENDSTARTTHIS——用来建立新的存储器地址操作数,但不分配存储单元。新的操作数类型在THIS中指定,而其段地址和偏移量就是汇编时的当前值。1234009185DSBUFFERWBUFFERAL=12HBX=3412H3.伪指令在8086/8088汇编语言中伪指令是用于诸如数据定义、存储区分配等功能。所谓伪指令是非机器指令,它是在汇编期间进行操作的。(1)符号定义语句EQU

为了使程序便于阅读和修改,我们有时使用一个符号来代表一个值,而符号代表了一定的意义,在程序中使用一个符号代表一个值进行操作,其格式为:

符号EQU表达式例如:

PORTEQU3F8H在程序中可使用

MOVDX,PORT

对DX进行赋值,实际上PORT就是一个常量。还可在语句中进行运算,如:

DATA_PORTEQU3F8HSTAT_PORTEQU3F8H+2

SEEDEQU10FUNCEQUSEED*SEED+2*SEED+1

‘=’号操作

对符号的赋值还可使用“=”操作,它与EQU的区别是“=”操作可以重复定义,而EQU则不能重复定义。如:

X=3Y=6Y=Y*Y-X……MOVAX,Y

通过上述操作,最后使Y=33,后面的MOV语句中,当生成目标代码时将用33取代Y。即

MOVAX,21H(33D)(2)数据定义语句

数据定义语句用于为数据分配相应的存储单元。用一个符号名代表一个或一些单元,并可为这个或这些单元提供初始值。定义数据的操作符有:

字节定义——DB

字定义——DW

双字定义——DD

四字定义——DQ

十字节定义——DT

重复定义——mDUP(n)(重复m次个数据n)与数据相联系的符号名称为变量。数据定义语句的格式为:

变量名操作符数据项

通过上述定义,在存储器中将产生如图所示的结果,以DATA1到DATA5为例:例:

DATA1DB?DATA2DW1000HDATA3DD3000A455HDATA4DW4DUP(0)DATA5DW0120H,0240H,0360H

DS随机001055A4003000000000200140026003DATA1DATA2DATA3DATA4DATA5DS544849532049532041204558414D504C45例:DATA6DB‘THISISAEXAMPLE’DATA6THIS

ISAEXAMPLE

注意:1:数据定义语句定义的数据在存储器中占有相应的单元,如上面语句中的第二句在程序运行时将会以00和10占据两中存储单元。而EQU只是定义了一个数据,在汇编后以实际数据的形式体现在程序中。也就是说,EQU语句不会占有存储单元。2:EQU可以用在指令中,而数据定义语句不可以。(3)段定义语句在段定义中,SEGMENT和ENDS总是成对使用的,它们将数据和程序分为多个段,如数据段、栈段和代码段。

ASSUME是汇编时进行操作的,它用于在汇编时告诉汇编器,哪个是数据段,哪个是代码段,哪个是栈段。

ORG用于指定目标程序存放单元的起始偏移地址,通常写在第一条源程序的前面,用于指定这段程序的首地址。如使用了:

ORG100则程序执行时就从CS:100处开始执行其后面的程序。

DATA_SEGSEGMENT

M1DW0058HM2DW012AHM3DW?M4DW?

DATA_SEGENDS

STACK_SEGSEGMENT

S_DATADB100DUP(?)TOPEQULENGTHS_DATA

STACK_SEGENDS

CODE_SEGSEGMENT

ASSUMECS:CODE_SEG,DS:DATA_SEG,SS:STACK_SEGSTART:MOVAX,DATA_SEGMOVDS,AXMOVAX,STACK_SEGMOVSS,AXMOVAX,TOPMOVSP,AX58002A01DSM1M2M3M4例:求出两个16位数M1和M2的积MOVBX,OFFSETM1MOVAX,[BX]MOVDX,0MOVBX,OFFSETM2MUL[BX]MOVBX,OFFSETM3MOV[BX],AXMOVBX,OFFSETM4MOV[BX],DXMOVAH,4CHINT21HDOCE_SEGENDSENDSTART58002A01DSM1M2M3M4

从上述程序中,我们可总结出如下结论:①SEGMENT和ENDS前面必须有标号,而且在相互配对的段,它们前面要使用相同的标号。对于不同的段定义标号,尽管这些标号可以是任意字串,但为了程序的可读性,应使其有一定的意义。②ASSUME语句可使汇编器知道CS、DS、SS指向哪个段,但它只在汇编时起作用,在运行时CPU并不知道除CS外的其它段地址,所以必须在程序中用指令进行赋值。③首条被执行的语句有一个标号,在程序的结尾使用END后跟上这个标号,用以标出这个程序的开始执行处。(4)过程定义语句和其它程序设计一样,8086/8088汇编程序设计有过程或子程序的设计方法。8086/8066汇编程序的过程从运行位置上分为近过程(NEAR)和远过程(FAR),其定义如下:

PROC_NAME1PROCNEAR……RETPROC_NAME1ENDP

PROC_NAME2PROCFAR……RETPROC_NAME2ENDP

过程和其它程序可定义在同一个段中,也可定义在不同的段中。对过程的调用要使用CALL语句,如:

CALLPROC_NAME1CALLPROC_NAME2

如果在过程定义中没有写明是NEAR过程或FAR过程,则汇编器将这个过程默认为NEAR过程。(5)程序开始和结束语句在程序的开始可以用NAME

或TITLE为程序取名字。格式为:NAME程序名

TITLE程序名

整个程序的结束使用END

标出,当汇编器读到END

时,它认为程序到此就结束了。在程序中,首条被执行的语句有一个标号,在程序的结尾使用END

后跟上这个标号,用以标出这个程序的开始执行处。

注:NAME、TITLE操作不是必须的。

END

则必不可少。(6)基数控制语句

汇编语言程序允许使用多种数制,如:二进制:00011101B

十六进制:0C5AAH

十进制:9856D

八进制:237O

通常默认数为十进制数,但用RADIX可以改变数制。

格式为:

RADIX表达式

例:MOVAX,2000H

MOVBX,30

RADIX16MOVAX,2000

MOVBX,30D汇编语言程序的执行过程:编辑程序.ASM

文件汇编程序.OBJ

文件连接程序.EXE

文件Edit等MASMLINK①根据问题提出相应的算法或逻辑过程;②

根据已确定的算法或逻辑过程画出程序流程图,把解题的思路和逻辑顺序以图示的方法表示出来。③

分配工作单元和寄存器。当然,在8086/8088汇编程序设计中,由于可用资源相对其它一些CPU和计算机系统较多,所以这项工作也可在程序编制中进行。

编写程序代码。二、汇编语言程序设计基础汇编语言程序设计与其它语言的程序设计一样,都要有良好的数据结构和算法,对每个要解决的问题要经过以下步骤:①程序的执行时间。每一条语句都有自己的执行时间,在8086/8088指令手册中每条指令的运行时间都有明确的定义。根据这些时间,我们可算出程序的运行时间。②程序所占有的字节数。有一些计算机系统,可能应用于工业控制或工业过程检测,不需要过多的硬件资源,比如存储单元,所以就要求我们的程序有尽可能少的字节数,以满足缩减硬件资源的要求。

③程序的语句行数。

在程序设计中,程序的效率是程序设计好坏的重要指标,特别是在汇编程序设计中,其特点要求我们对程序运行的效率加以重点关注。对于汇编语言程序我们可以考虑以下几方面作为程序运行效率的衡量标准:

另外,在程序设计中对语句的使用要有灵活性。例1:将一个字节乘以128例2:数AL中的“1”的个数。我们可以通过:时钟周期字节数

MOVAL,DATA42MOVBL,12842MULBL702也可以通过

MOVAH,042

MOVAL,DATA42MOVCL,742SHLAX,CL82还可以通过

MOVAH,DATA42MOVAL,042SHRAX,122来完成。

从运行时间上,后一个要快于前一个程序。例1:将一个字节乘以128程序1:

MOVAH,0MOVCX,8AGAIN:SHLAL,1JCADD1JMPNEXTADD1:INCAHNEXT:LOOPAGAIN

HLT程序2:

MOVAH,0CLCAGAIN:SHLAL,1ADCAH,0ORAL,ALJNZAGAINHLT显然,程序2在运行效率和程序行数上都优于程序1。例2:数AL中的“1”的个数:三、

直线程序

直线程序设计是程序设计中最简单的设计方法,它是将确定好的算法或逻辑关系以正确的语句和正确的逻辑关系有序地编写出来,形成程序。例5-1:求两32位无符号数的乘积。在8086/8066中,单个可处理数据的最大位数为16位,所以在计算中不能一次将两个32数的积求出,所以可通过部分积的求法,求出它们的积。算法如下图。

D11D12D21D22×D12×D22D11×D22D12×D21D11×D21+部分积1部分积2部分积3部分积4结果

DXAXDXAXDXAXDXAX

NAME32BITMULTIPLYDATASEGMENTMULNUMDW0010,0A100H,0000,0FFFFH,4DUP(?)DATAENDSSTACKSEGMENTPARA‘STACK’DB100DUP(?)TOPEQULENGTHSTACKSTACKENDS

CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKSTARTPROCFAR;将本程序作为DOS操作系统的子程序。

BEGIN:PUSHDS

XORAX,AXPUSHAX;标准程序前缀

MOVAX,DATAMOVDS,AXMOVES,AXSegment的类型及属性说明在需要用连接程序将本程序与其它模块相连接时,需要使用这些说明。

MOVAX,STACKMOVSS,AXMOVAX,TOPMOVSP,AX;以上为设置段地址

;和栈指针

LEABX,MULNUM

;取数据的首地址MUL32:MOVAX,[BX]

;取D12至AXMOVSI,[BX+4]

;取D22至SIMOVDI,[BX+6]

;取D21至DIMULSI

;D12×D22MOV[BX+8],AX

;存部分积1

MOV[BX+0AH],DXMOVAX,[BX+2];取D11至AXMULSI

;D11×D22ADDAX,[BX+0AH]ADDDX,0

;部分积相应部分相加

MOV[BX+0AH],AXMOV[BX+0CH],DX

;存中间结果

×D12×D22D11×D22D12×D21D11×D21+部分积1部分积2部分积3部分积4结果DXAXDXAXDXAXDXAXD11D12D21D22100000A10000FFFFD12D11D22D21MULNUMMOVAX,[BX];取D12至AXMULDI;D12×D21

ADDAX,[BX+0AH]ADCDX,[BX+0CH];部分积相应部分相加

MOV[BX+0AH],AX;存中间结果

MOV[BX+0CH],DXPUSHF;保存上次计算的进位位

MOVAX,[BX+2];取D11至AXMULDI;与D21相乘

POPF;取上次的进位位

ADDAX,[BX+0CH]ADCDX,0;部分积相加

MOV[BX+0CH],AXMOV[BX+0EH],DX;存结果

RET

;返回到DOSStartendpCODEENDSENDBEGIN

×D12×D22D11×D22D12×D21D11×D21+部分积1部分积2部分积3部分积4结果

DXAXDXAXDXAXDXAXD11D12D21D22100000A10000FFFFD12D11D22D21MULNUMSegnamesegment[align_type];定位类型

[combine_type];组合类型

[‘class’];类别定位类型:

para:指定段的起始地址必须从小段边界开始,即段地址的最后1位(十六进制)必须为0

byre:该段可以从任何地址开始。

word:该段必须从字的边界开始,即段地址必须是偶数。

page:该段必须从页的边界开始,即段地址的最后2位(十六进制)必须为0

。组合类型:

public:该段连接时将与有相同名字的其它段连接在一起。

common:该段在连接时与其它同名分段有相同的起始地址(会产生覆盖)。

atexpression:使段的起始地址是表达式所指定的16位段地址,但不能指定代码段。

stack:指定该段在运行时为堆栈段的一部分。类别:连接时用于组成段组的名字。

Segment的类型及属性说明——在需要用连接程序将本程序与其它模块相连接时,需要使用这些说明。程序段前缀PSP

汇编语言程序经过编译、连接后生成.EXE文件;该文件可在PC-DOS支持下装入内存,并从程序中指定的地址处开始运行。这个工作由PC-DOS

的COMMAND.COM文件中的EXEC来完成。

COMMAND.COM的工作:

①在装入这个文件之前,先在这个程序段内偏移地址为0000H

处构造一个

100H

字节的程序段前缀

PSP(ProgramSegmentPrefix)控制块;

②然后开始装载程序,并将控制权交给装入的指令。

程序段前缀PSP实际上是一个程序控制块,PC-DOS建立这个程序控制块,并用它来管理程序的进程。

PSP结构为:

偏移地址分配情况

00~01H指令INT20H(DOS中断——程序终止退出)

02~03H可利用的内存空间(以16字节为单位)

04H保留

05~09H远调用指令CALL功能入口

0A~0DH程序结束地址INT22H0E~11HCTRL-BREAK出口地址INT23H12~15H标准错误出口INT24H16~22H保留

2C~5BHDOS专用

5C~6BHFCB1(文件控制块)格式化参数区16C~7BHFCB2格式化参数区27C~7FH保留

80~FFH隐含的磁盘传输区(DAT)

PC-DOS通过程序段前缀PSP来管理程序,因此,设计一个.EXE

文件的源程序时,需要依赖

PSP

中的信息来构成一个完整的运行文件。

.EXE文件汇编源程序的标准前缀

当加载.EXE

文件时:

•CS、IP、SS、SP的值由连接程序确定(由用户在设计源程序时定义);

DS、ES段寄存器被设置为PSP

的段基址。因此,PC-DOS可通过DS、ES通知用户当前PSP的段基址。CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKSTARTPROCFAR;将本程序作为DOS操作系统的子程序。

BEGIN:PUSHDSXORAX,AXPUSHAX

;标准程序前缀

MOVAX,DATAMOVDS,AXMOVES,AX······

RETSTARTENDPCODESEGMENTENDBEGIN

标准程序前缀

PSP

的00~01H处,是一条INT20H指令,即终止程序正常返回DOS。

而要执行INT20H,必须保证CS

的值是PSP

的段基址,

IP

的值为

0000

故,通常在.EXE文件的源程序的开始处都把PSP

的段基址保留在堆栈段的顶端,这样,当程序最后用RET指令返回时,将控制权交给PSP

段基址中的INT20H,则一定能返回DOS。所以,这个程序段叫标准程序前缀,放在代码段中程序的开始处。PUSHDSXORAX,AXPUSHAX

······RET(IP)<-(SP+1),(SP)SP<-SP+2(CS)<-(SP+1),(SP)SP<-SP+200006F27SS276F:0000CD20···PSP①②③如果不使用程序段前缀PSP返回DOS,则可以这样完成程序:CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVES,AX······

MOVAH,4CHINT21H;DOS功能调用,结束程序,返回DOSCODESEGMENTENDBEGIN四、分支程序在很多实际问题中,通常要根据不同的情况,执行不同的程序块或语句,这就需要在设计程序时使用运算后的结果,依据一定的条件进行相应的判断,根据判断结果的真或假,去运行相应的程序或语句。例2:有一数学函数如下:

1x>0y=f(x)=0x=0-1x<0

要求写出程序完成上述计算。X=0X>0Y=0Y=1Y=-1YYNN框图如下开始DATASEGMENTXDW?DATAENDS

CODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAX,XORAX,AXJEZEROJNSPLUSMOVBL,0FFHJMPHALTZERO:MOVBL,0JMPHALTPLUS:MOVBL,1HALT:MOVAH,4CHINT21HCODEENDSENDSTART

在上面的程序中,要特别注意其中的两中JMPHALT的使用,从而保证每个分支的完整性。五、循环程序对于程序中多次、有规律执行的部分,我们通常使用循环结构要重复运行这些部分,使程序有较高的运行效率和可读性。循环结构主要由三部分组成,它们是:

1.循环体:重复运行的部分,其中还包含了工作部分和循环控制部分。工作部分进行相应的操作,而循环控制部分则保证在不满足循环条件时,跳出循环。

2.循环结束条件:在循环体中包括了循环结束条件运算部分。每循环一次除了工作部分进行相应的操作外,循环条件部分还要通过运算,得出当前循环的状态,以便在适当的条件下结束循环。

3.循环初值:用于设置开始循环时,循环体所处的初始状态,如循环变量初值,循环体中用到的数据和地址指针等。DATASEGMENTSUMDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTARTPROCFARBEGIN:

PUSHDSXORAX,AXPUSHAXMOVAX,DATAMOVDS,AXMOVCX,10MOVAX,0AGAIN:ADDAX,CXLOOPAGAINMOVSUM,AX

RETSTARTENDPCODEENDSENDBEGIN

该程序是一个以计数器为循环条件的循环结构,是循环中常见的结构之一。例3:求1-10的累加和。DATASEGMENTSTRDB‘THISISASTRING$’LENDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTARTPROCFARBEGIN:PUSHDSMOVAX,0PUSHAXMOVAX,DATAMOVDS,AXMOVCX,0LEABX,STRAGAIN:MOVAL,[BX]CMPAL,‘$’JZHALTINCCXINCBXJMPAGAIN上述程序是一个以控制条件为循环条件的循环结构。HALT:MOVLEN,CX

RET

STARTENDPCODEENDSENDBEGIN例4:有一以“$”结束的字串,请求出它的长度。

DELAY:PUSHAXPUSHDX

MOVDX,3FFH

TIME1:MOVAX,0FFFFH

TIME2:DECAXNOPJNETIME2

DECDXJNETIME1POPDXPOPAXRET

在循环中,多重循环也是程序设计中常用的结构之一,多重循环通常有多个循环变量。在多重循环中,各自的循环变量要明确,否则将导致循环体的混乱。以两重循环为例,外层循环的循环次数为N,内层循环次数为M,则内层体被运行了N×M次。下面是一个用于延时的子程序。多重循环的程序设计例5:延时子程序例6:设有数组X[x1,x2,x3···,x10],数组Y[y1,y2,y3···,y10],试编程计算z1=x1-y1z2=x2+y2

z3=x3-y3

z4=x4+y4z5=x5-y5z6=x6-y6

z7=x7+y7z8=x8-y8z9=x9-y9

z10=x10-y10开始初始化:设逻辑尺,地址指针,循环次数i=0测试逻辑尺第i位的值

=0?Xi-yiXi+yiZi<-结果i<-i+1循环结束?结束nyyn设逻辑尺:0000001010110111DatasegmentXdb11,22,33,44,45,66,77,88,99,100Ydb1,2,3,4,5,6,7,8,9,10Zdb10dup(?)Logruledw0000001010110111bDataendsCodesegmentassumecs:code,ds:dataStartprocfarBegin:pushdsxorax,axpushaxmovax,datamovds,ax

movbx,0movcx,10

Movdx,logruleagain:movax,x[bx]shrdx,1jcsubtractaddax,y[bx]jmpresultSubtract:subax,y[bx]result:movz[bx],axincbxincbx

loopagainretstartendp

codeendsendbegin上述程序为用逻辑尺控制循环的循环结构。例7:若自Block开始的内存中有100个带符号数,找出最大值存入Max单元。DatasegmentBlockdw11,22,33,44,45,66,77,88,99,100……Maxdw?DataendsCodesegmentassumecs:code,ds:dataStartprocfarBegin:MOVBX,OffsetBlock

MOVAX,[BX]

INCBX

INCBX

MOVCX,99Again:CMPAX,[BX]JGNEXTMOVAX,[BX]Next:INCBXINCBXDECCXJNZAgain

Block65F3020024E00500Max

MOVMAX,AXRetStartendpCodeendsendbeginCODESEGMENTASSUMECS:CODEBegin:MOV BX,1234H;0001,0010,0011,0100 MOV CH,4 ;CH做循环计数器ROT: MOV CL,4 ;CL做移位计数器

ROL BX,CL ;将最高4位移到低4位,0010,0011,0100,0001

MOV AL,BL AND AL,0FH ;取出低4位

ADD AL,30H ;转换为ASCII码

CMP AL,39H ;与’9’比较

JBE DISP ;若(AL)≤‘9’,则转显示

ADD AL,7 ;若(AL)>’9’,再加7转为‘A’-‘F’DISP: MOV DL,AL ;(DL)←字符

MOV AH,2

INT 21H ;显示输出

DEC CH ;4个十六进制数显示完否?

JNZ ROT ;没有,循环

MOVAH,4CHINT21HCODEENDSENDBEGIN例8:以十六进制数形式显示BX中的内容。六、码转换程序设计

输入输出设备以ASCⅡ码表示字符、数字;

在机器内部,以二进制(十六进制)表示;

我们习惯使用十进制数。

因此需进行数制的转换。

ASCII码美国标准信息交换代码DecchJnzrotateRetMainendpCodeendsendbeginBX1010110001011001000011111100010110011010①②∧00001010CodesegmentMainprocfarassumecs:codeBegin:pushdsxorax,ax

pushaxmovch,4

movcl,4Rotate:rolbx,clmoval,bl

andal,0fh

addal,30hcmpal,3ahjlprintf

addal,7hPrintf:movah,2movdl,alint21h例1:将BX寄存器中的二进制数以十六进制的形式在显示器上显示出来。例2:将二进制数串转换成ASCII码,并在屏幕上显示。DatasegmentNumdw4f78h;0100111101111000BStringdb16dup(?)DataendsCodesegmentassumecs:code,ds:dataStartprocfarBegin:pushdsmovax,0pushaxmovax,datamovds,axmovbx,numleasi,string

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论