第3章 常用伪指令与汇编语言程序设计(2)-顺序程序与分支程序_第1页
第3章 常用伪指令与汇编语言程序设计(2)-顺序程序与分支程序_第2页
第3章 常用伪指令与汇编语言程序设计(2)-顺序程序与分支程序_第3页
第3章 常用伪指令与汇编语言程序设计(2)-顺序程序与分支程序_第4页
第3章 常用伪指令与汇编语言程序设计(2)-顺序程序与分支程序_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

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

文档简介

3.3.程序的基本结构最基本的程序结构:顺序结构、分支结构、循环结构。AB顺序结构分支结构判断ABNYABC1ABC2ABC3子程序、中断服务程序是一种特殊的程序,它们也是由以上三种基本结构构成的。i=初值A修改并判断iYN循环结构BGLUT_C2013-08J.CB13.3.1简单程序设计例:编写程序将字变量W中的无符号数W=65525除以8,将商保存在字变量QOUT中,将余数保存在字节变量REMA中。算法分析:可以使用除法指令,也可以使用右移三位实现除以8的运算。65525→0FFF5H11111111

11110101B(1)右移3位,移出的三位就是余数,剩余的就是商。余数的保留:可以选择两种方法GLUT_C2013-08J.CB211111111

11110101CREMA→→0111111111111010C10000000→→0011111111111101C01000000→→000111111111110C10100000→→10100000右移5位00000101GLUT_C2013-08J.CB3开始定义W、QOUT、REMAAX←W,BL←0AX右移1位,最低位移进CBL右移1位,C移入它的最高位AX右移1位,最低位亦如CBL右移1位,C移入最高位AX右移1位,最低位亦如CBL右移1位,C移入最高位QOUT←AXBL右移5位,REMA←BL结束使用伪指令定义W、QOUT、REMA三个内存单元,W、QOUT为16位,REMA为8位。这里的结束是结束应用程序,返回操作系统。可以使用INT21H的4CH号功能调用返回操作系统

MOV AH,4CHINT 21HGLUT_C2013-08J.CB4DATASEGMENTDATAW DW 65525QOUT DW ?REMA DB ?DATAENDSCODE SEGMENTCODEASSUMECS:CODE,DS:DATASTART:MOV AX,DATA ;取数据段开始地址

MOV DS,AX ;数据段开始地址送数据段基址寄存器

MOV AX,W ;从存储器取出DS:WAX MOV BL,0 ;余数寄存器清0 SHR AX,1 ;无符号数,逻辑右移1位,高位移入0, ;W最低位进入C RCR BL,1 ;带进位循环右移1位,C进入BL最高位

SHR AX,1 ;逻辑右移1位,高位补0,W次低位进入C RCR BL,1 ;带进位循环右移1位

SHR AX,1 ;逻辑右移1位,高位补0,W次低位进入C RCR BL,1 ;带进位循环右移1位,余数在BL高3位

MOV CL,5数据段结束代码段开始数据段开始GLUT_C2013-08J.CB5

SHR BL,CL ;余数右移5位,将其移到BL低3位

MOV QOUT,AX ;保存商

MOV REMA,BL ;保存余数

MOV AH,4CH INT 21HCODEENDS END本程序是返回操作系统代码段结束汇编源程序结束GLUT_C2013-08J.CB6还有就是:W直接取低3位作为余数然后W右移3位得到商开始定义W、QOUT、REMAAX←W,REMA←7REMA←REMAANDALAX右移3位QOUT←AX开始AX右移3位:MOVCL,3SHRAX,CL注意:如果是带符号数,就要用算术右移SAR,不要用逻辑右移SHRGLUT_C2013-08J.CB7

…… MOV AX,W ;从变量W取数据

MOVREMA,7 ;余数变量REMAP赋值00000111B AND REMA,AL ;余数是AL的最低3位,

MOVCL,3 ; SHR AX,CL ;逻辑右移3位,AX中得到商

MOV QOUT,AX ;保存商

MOV AH,4CH INT 21H该程序结果相同,但程序代码简单了,执行速度也快了GLUT_C2013-08J.CB8(2)使用除法指令

DIVsrc注意:对于8086处理器为了商是字数据,被除数32位:DXAX(DX=0,AX=W)除数16位BX=8DIVBX商在AX,余数在DX,对于本次运算,余数为字节数据,实际上只有DL有效.DATAW DW65525QOUTDW?REMADB?.CODE MOV AX,DATA MOV DS,AX MOV DX,0 MOV AX,W MOV BX,8 DIV BX MOV QOUT,AX MOV REMA,DL MOV AH,4CH INT 21H END如果是带符号数,应该使用符号扩展指令CWD和带符号除法指令IDIV由于题目指定是无符号数,这里可以将高16位扩展为0,用DIV除法指令GLUT_C2013-08J.CB9例将AX中的3位BCD数转换为二进制数存入字节变量SB中(AX中的数大于0,小于255)每位十进制用一个8421编码(自然二进制编码)表示(即每一位十进制数都是用二进制表示)十进制数的展开表达式3位BCD码N2N1N00ALAHGLUT_C2013-08J.CB10主要部分程序流程图AL=AL+AHAL=AL*CHAHBLAL=百位*10既执行AL=AL*CHAL=BLand0FHAL=AL+BL因百位*10不会大于255,AH=0,可以使用AH右移4位,高位补0得到十位数ALSB保留个位十位到BL取百位到ALALAHCH10,CL=4AH=BLAH右移4位得到十位由于题目给出不大于255,因此最后一次乘10加个位也只是一个字节相加GLUT_C2013-08J.CB11

M0VCH,10 MOVCL,4 MOVBL,AL ;暂存十位和个位到BL, MOVAL,AH ;百位存入AL中

MULCH ;百位×10→AX MOVAH,BL SHRAH,CL ;取十位

ADDAL,AH ;百位×10+十位→AL MULCH ;(百位×10+十位)×10→AX ANDBL,0FH ;取个位

ADDAL,BL ;(百位×10+十位)×10+个位→AL

;约定结果不大于255 MOV[SB],AL;AL→SB,如果没有明确结果不大于255,则需要考虑16位结果GLUT_C2013-08J.CB120~999的BCD数转换为二进制,主要部分程序流程图AL取百位AX百位*10AH取十位百位*10+十位AL=AL+AHAX=AL*10BX=BXand0FHAX=AX+BX因百位*10不会大于255,AH=0,可以使用AH右移4位,高位补0得到十位数AXSBSB应该是字操作数(16位)加个位,BH要清0AX为000~999之间的BCD数(百位*10+十位)*10GLUT_C2013-08J.CB13

M0VCH,10 MOVCL,4 MOVBL,AL;暂存十位和个位到BL, MOVAL,AH;百位存入AL中

MULCH;百位×10→AX MOVAH,BL SHRAH,CL;取十位

ADDAL,AH;百位×10+十位→AL MULCH;(百位×10+十位)×10→AX ANDBX,0FH;取个位

ADDAX,BX;(百位×10+十位)×10+个位→SB

;最后结果为16位数,不能简单+低8位

MOV[SB],AX;AXSBGLUT_C2013-08J.CB14

简单程序设计例下面再看几个补充的例题。例

:将存储器单元DAT1中保存的一个组合BCD数转换成两个对应ASCII码值,并存入DAT2开始的两个单元,低位在前,高位在后。GLUT_C2013-08J.CB15BCD码转换成ASCII码数据:非压缩BCD数据在高半字节+3.例如数字55:0000010100110101000001010011000000110101用逻辑或指令OROR000001010011000000110101用加法指令OR+得到的结果是相同的。都是在高半字节加3。GLUT_C2013-08J.CB16该问题算法就很简单:从DAT1取出BCD数据,先将高4位清“0”,与30H相加或进行逻辑或运算,存入DAT2,再取出数据,将数据逻辑右移4位(高位BCD数移到低4位,高4位变“0”,再与30H相加(或进行逻辑或),存入DAT2+1单元。程序流程图:GLUT_C2013-08J.CB17程序流程图程序代码DATASEGMENT DAT1DB34H

;待转换的数 DAT2DB?,?DATAENDSCODESEGMENTASSUMECS:CODE,

DS:DATASTARA:

MOVAX,DATA MOVDS,AX

;送段地址

LEASI,DAT1LEADI,DAT2 MOVAL,[SI] ANDAL,0FH ADDAL,30H MOV[DI],AL MOVAL,[SI]

开始段定义AL(SI)AL(AL)�FH(DI)(AL)+30HAL(SI)结束AL(AL)右移4位(DI+1)(AL)+30H设置DS,SIDAT1DIDAT2显示:MOVDL,ALMOVAH,02HINT21HGLUT_C2013-08J.CB18

MOVCL,4SHRAL,CLORLAL,30H MOV[DI+1],AL MOVAH,4CH INT21HCODEENDS ENDSTART如果要送到屏幕显示,则将转换结果先送DL,02送AH,调用DOS功能。送ASCII字符显示的系统调用: 功能AH=02H,

需要显示的字符ASCII码DL

, 执行INT21H显示:MOVDL,ALMOVAH,02HINT21HAH=4CH功能调用。功能是结束本程序,返回DOSGLUT_C2013-08J.CB19再看一个顺序程序:

编写一个计算Z=(x2-3y)/2的程序,x,y为单字节正整数,Z用2字节保存。这是一个算术运算程序,算法设计:首先计算X2=X*X,暂存该结果,其次计算3*y,第三步计算X2-3*y第四步计算(x2-3y)/2。该步使用算术右移实现除2运算,比用除法指令执行速度快。依据该算法,可以画出程序流程框图。GLUT_C2013-08J.CB20开始计算Z=x*x计算Z=(X*X-3Y)/2结束计算3*yX2的计算,可以分解为3*Y的计算,可以分解为ALxMULALBXAXCXAXADDAX,CXADDAX,CXALY,AH=0GLUT_C2013-08J.CB21;数据段定义

DATA SEGMENT X DB25 Y DB32 Z DW ? DATAENDS;代码段开始

CODE SEGMENT ASSUMECS:CODE,DS:DATA

EXPREPROCFAR

;过程定义,远过程 START:PUSHDS;DS:00保存的是一条返回

SUBAX,AX ;DOS指令。

PUSHAX ;这里,将返回DOS的地址

;压入堆栈

MOVAX,DATA操作系统会自动在DS:00处安排一条返回操作系统的指令,故子程序开始处向堆栈中压入DS:00执行RET指令,则就是转到DS:00——返回DOSGLUT_C2013-08J.CB22 MOVDS,AX

;数据段首地址(基地址) MOVAL

,

X

;取变量X

MOVBL,AL

MULBL ;X*X=X2

MOVBX,AX

MOVAL,

Y

;取变量Y

MOVAH,0 ;正整数,高字节直接扩展0

MOVCX,AX ADDAX,CX ;2Y ADDAX,CX ;3Y

XCHGAX,BX

SUB

AX,BX

;X2-3Y SHR

AX,1

;右移一位/2 MOV

Z,

AX RET ;将DS:00弹出到CS:IP

EXPREENDP;过程定义结束CODEENDS ENDSTARTRET指令,转到DS:00,对于EXE格式程序,它是一条返回DOS的指令。GLUT_C2013-08J.CB23;数据段定义

DATA SEGMENT X DB25 Y DB32 Z DW ? DATAENDS;代码段开始

CODE SEGMENT ASSUMECS:CODE,DS:DATAMOVAX,DATA MOVDS

,

AX MOVAL

,

X MOV BL,AL可以使用常规返回DOS方法——INT21H的4CH功能调用GLUT_C2013-08J.CB24

MULBL ;X*X=X2

MOVBX,AX

MOVAL,

Y

;Y

MOVAH,0

MOVCX,AX ADDAX,CX ;2Y ADDAX,CX ;3Y

XCHGAX,BX

SUB

AX,

BX

;X2-3Y SHR

AX,1

;右移一位/2 MOV

Z,

AX MOVAH,4CH INT21H EXPREENDP;过程定义结束

CODEENDS ENDSTART用INT21的4CH号功能调用返回DOS。GLUT_C2013-08J.CB25例BCD加法程序例如:已知字变量W1、W2分别存放两个非压缩的BCD数,编写程序求两数之和,并将结果存入SUM字变量中。注意:W!,W2为2为字变量(2字节)压缩BCD数,00~99,它们的和则可能为3位BCD数,故SUM应该定义3个字节(用DB定义三个字节)。计算机内部只有二进制运算指令,对于BCD数运算,是十进制数,用二进制运算指令运算,需要进行调整。 加法、减法、乘法在运算后进行调整 除法在运算前先进行调整。只有字节运算才能进行调整

非压缩BCD数加法调整AAA(压缩BCD数加法用DAA)GLUT_C2013-08J.CB26压缩BCD加法后,用DAA调整非压缩BCD加法后,用AAA调整压缩BCD减法后,用DAS调整非压缩BCD加法后,用AAS调整压缩BCD加法后,用AAM调整(压缩的BCD乘法,不能调整)除法指令前用AAD调整(存放在AX中的两位非压缩BCD数)开始定义W1、W2、SUMAL←W1第一字节(个位)ADDAL,W2第一字节,AAAC送SUM+2最低位(百位)结束SUMALAL←W1第二字节(十位)ADCAL,W2第二字节,AAASUM+1AL将SUM+2清0,然后进行带进位的循环左移,就可将CY移进SUM+2最低位,其余位=0GLUT_C2013-08J.CB27例如:0809+0607=010506,程序段如下:DATASEGMENTW1DW0809HW2DW06078HSUMDB3DUP(0)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKMOVAX,DATAMOVDS,AX ;MOVAL,BYTEPTRW1

;取第一个数,AL=09HADD

AL,BYTEPTRW2

;AL=09H+07=10h,AF=1AAA

;AL=06H,产生CF=1

MOV[SUM],AL;保存个位,进位信号在CFMOVAL,BYTEPTRW1+1;AL=08H

GLUT_C2013-08J.CB28

ADCAL,BYTEPTRW2+1;AL=0FH,CF=0AAA

;AL=05H,CF=1MOVSUM+1,AL;存百位和千位

MOVSUM+2,0;处理向百位的进位,先将SUM+2RCLUM+2,1 ;清0,然后用带进位循环左移指

;令将进位位移到SUM+2最低位实际上,在SUM定义时,已经初始化为0,程序中可以不清0定义的变量W1,W2,SUM在汇编语言源程序中可以直接使用,汇编程序在对源程序进行汇编时,可以识别是从变量所存放的存储器中取出数据——实际上就是汇编程直接寻址指令

MOVAL,[W1],为了书写简单,我们直接写成MOVAL,W1.GLUT_C2013-08J.CB29以上例子,有一些只给出了实现所要求功能的核心部分分代码,没有给出段定义的完整部分。有一些则给出了包含段定义的完整代码;段定义的格式是相似的,可以参照教材上的例子和前面的段定义例子编写。教材上还有一些顺序程序的例子,由于时间关系,就不一一列举了。GLUT_C2013-08J.CB30顺序程序的结构简单,但实际程序设计中,往往需要对某些条件进行判断,依据不同的条件执行不同的分支,这样,顺序程序将不能满足要求。GLUT_C2013-08J.CB313.3.2

分支程序的设计

就是利用CPU的条件转移指令,通过判断某个标志为的状态,控制程序的执行过程。PF=0奇转移JNP/JPOPF=1偶转移

JP/JPEOF=0无溢出转移JNOOF=1溢出转移JOSF=0为正转移JNSSF=1为负转移JSCF=0无进(借)位转移JNCCF=1有进(借)位转移JCZF=0不相等/不等于0转移JNE/JNZZF=1相等/等于0转移JE/JZ标志设置功能指令助记符GLUT_C2013-08J.CB32二分支结构分支结构判断ABNYABC1ABC2ABC3分支结构判断BNYABC1ABC2GLUT_C2013-08J.CB33多分支结构条件判断1Y……程序1N条件判断2Y程序2条件判断n程序nY程序n+1NNGLUT_C2013-08J.CB34也可以按照条件编码实现多分枝转移例如段内间接转移指令JMPREG转移到CS:AXJMPWORDPTRMEM转移到CS:[MEM]AX←条件编码CODAX←AX*kJMPAX分支程序0分支程序1分支程序nCOD=0COD=1COD=nK是一个不小于2的整数。GLUT_C2013-08J.CB35我们还是通过实例来讨论。例:内存单元M中有一个16位的带符号数,求它的绝对值,并将结果放回原处。

算法:求一个数的绝对值时,如果是正数,绝对值不变,如果是负数,则求它的机器负数(连同符号位一起每位取反,最低位+1,就是使用NEG指令)。有了算法,可以画出程序流程图。GLUT_C2013-08J.CB36转移目的指令给出标号(符号地址)开始设置DSSIMAX[SI]ORLAX,AXSF=0NEGAXNYDONE[SI](AX)结束N_DATAN_DATA,负数,该标号为了阅读程序方便判断数据的符号,在X86中就是判断SF标志位,数据传送指令不改变标志位,因此用一条逻辑运算指令ORLAx,AX,它不改变AX的值,但设置标志位SFGLUT_C2013-08J.CB37

DATASEGMENT

MDW789AH ;可以任意输入一个数

DATAENDSCODESEGMENT

ASSUMECS:CODE2,DS:DATA2START:MOVAX,DATA MOVDS,AX LEASI,M;MOVSI,OFFSETM MOVAX,[SI] ORLAX,AX;ANDAX,AX JNSDONE

;符号为SF=0转移到DONEN_DATA:NEGAX

;负数,利用NEG指令求负DONE:MOV[SI],AX MOVAH,4CH INT21HCODEENDSEND

GLUT_C2013-08J.CB38多分支程序对分支程序,可以由这种2分支程序构成。满足条件1?NYFUN1满足条件2?满足条件3?分支4分支3分支2分支1YYNNFUN2FUN3FUN4FUN5TST2TST1TST3GLUT_C2013-08J.CB39计算函数的程序,x是十六位长度字数据算法分析:取出数据X,判断它的符号,首先判断是否>=0,如果不是,则是负数,Y=-1,如果是,还须再次判断是否等于0。程序流程框图为:GLUT_C2013-08J.CB40开始段定义及初始化取数据-->AX(AX)≥0?(AX)=0?Y=-1Y=0Y=1结束YYNNLP1LP3LP2END1画流程图的时候,对转移目标地址(最好是分支程序的两个分支点)都给出一个标号,在写代码时好使用LP0GLUT_C2013-08J.CB41DATASEGMENT

XDW-8

YDB?DATAENDSCODESEGMENT

ASSUMECS:CODE3,DS:DATA3START: MOVAX,DATA3;设置段基址

MOVDS,AX LEASI,X ;取偏移地址

MOVAX,[SI] ANDAX,AXGLUT_C2013-08J.CB42

JNSLP1 ;SF=0,转到LP1LP0:

MOVY,0FFH ;<0,Y=-1的补码

JMPEND1LP1:

JZLP3

;X>=0,继续判断,

;=0转到LP3LP2:

MOVY,01H ;X>0时,y=1 LJMPEND1LP3:

MOV Y,00H ;X=0时,Y=0END1:

MOVAH,4CH ;返回操作系统 INT21HCODEENDS ENDSTARTGLUT_C2013-08J.CB43教材上有一个例子(102页例3.7)算法分析:取出数据X,Y,异或,判断符号,SF=1,表明符号异号Z=0;SF=0,表明符号相同,判断是否X>0,是,Z=1,否Z=-1。GLUT_C2013-08J.CB44多分支的另一种实现方法除了用二分支指令实现多分支外,还可以用以下指令实现:

JMPREG ;

JMPWORDPTRMEM例如,我们要依据AL中的低4位数据(0~15)不同,分别转移到对应的分支去执行,每个分支约定占用200字节空间。这类指令应用方法如下:GLUT_C2013-08J.CB45

ANL AL,0FH MOVBL,100 MUL BL MOV AX,FUN0 ; JMP AXFUN0: ….

ORGFUN0+100

FUN1: … ;FUN1-FUN0=100

;可以用定位伪指令确定每个… ;分支相距的距离

ORGFUN14+100 ;只要保证这段空间能存下FUN15: … ;这段代码。也可以是一个转移表,利用远转移指令转到各处理程序,这样各功能分值的距离就比较小,而且相距的字节数也相同。GLUT_C2013-08J.CB46例3.9从键盘上键入2位十六进制数将其拼合成一个字节存入字节变量SB中。DATASEGMENT IBUF DB3,0,3DUP(0) SB DB0DATAENDSCODESEGMENT ASSUMECS:CODE,DS:DATA MOV AX,DATA MOV DS,AX MOVDX,OFFSETIBUF;键入2位十六进制数

MOVAH,10 INT21H MOVAX,WORDPTRIBUF+2;键入字符从+2单元开始,取出送AX

SUBAX,3030H ;字符变为十六进制数

CMPAL,0AH JBLNSUB7 ;0·9,ASCII-30H就是它对应的HEX值

SUBAL,7 ;A·F,ASCII-37H就是它对应的HEX值GLUT_C2013-08J.CB47LNSUB7:CMPAH,0AH JBLNSUB7 SUBAH,7HNSUB7:MOVCL,4 ;将AX中的数拼合成一个字节

SHLAL,CL ORAL,AH MOVSB,AL MOVAH,4CH INT21HCODEENDS ENDGLUT_C2013-08J.CB48例3.10某工厂的产品有8种不同的加工处理程序P0~P7,根据键盘输入,做不同的处理,若是0~7以外的键,则退出加工处理

此例可以用两种方法实现:一种是用逐一比较判断,逐次比较转移实现二叉分支、整体上实现多分支;另一种是跳转表法,直接实现多分支.GLUT_C2013-08J.CB49方法一︰逐一比较法.简单,条理清楚,易于实现,但转移范围只能是:-128~+127DATA SEGMENT INPUTDB’Input(0~7):$’DATAENDSCODESEGMENT MOV AX,DATA MOV DS,AX

MOVDX,OFFSETINPUT

;显示提示符

MOVAH,9 ;09号功能是显示字符串,$是字符串结束符

INT21H ;

MOVAH,1

;等待键入一个字符到AL,

INT21HCMPAL,’0’

;为0字符则转P0

JEP0CMPAL,’1’

;为1字符则转P1

JEP1GLUT_C2013-08J.CB50

CMPAL,’2’ JEP2 CMPAL,’3’ JEP3 CMPAL,’4’

JEP4 CMPAL,’5’ JEP5 CMPAL,’6’ JEP6 CMPAL,’7’ JEP7 JMPDOWN

温馨提示

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

评论

0/150

提交评论