第7章 汇编语言程序设计 (版本)_第1页
第7章 汇编语言程序设计 (版本)_第2页
第7章 汇编语言程序设计 (版本)_第3页
第7章 汇编语言程序设计 (版本)_第4页
第7章 汇编语言程序设计 (版本)_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

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

文档简介

2023/2/51/41第7章汇编语言程序设计7.1程序设计步骤7.2简单程序7.3分支程序7.4循环程序7.5子程序习题7.1程序设计步骤2023/2/52/41汇编语言程序设计步骤:

(1)分析问题:已知条件、要解决的问题、功能/性能要求等。

(2)建立数学模型:把问题数学化、公式化,便于计算机处理。

(3)确定算法:简单、速度快、精度高、代码量小、编程容易。

(4)绘制程序流程图:用箭头、框图、菱形图等表示程序结构。

(5)内存空间分配:为程序或数据分配内存空间。

(6)编制程序与静态检查:程序结构层次简单、清楚、易懂。

(7)程序调试:利用调试软件DEBUG进行调试。2023/2/53/41汇编语言程序设计的特点:

(1)算法要分解至指令级;高级语言为语句级。

(2)要详细考虑内存空间分配问题:

任何一个变量、一条指令都要明确其存储位置7.2简单程序

这种程序的形式最简单,计算机执行程序的方式是“从头到尾”,逐条执行指令语句,直到程序结束。这类简单程序不用按上述7个步骤,可直接对给出的题目写出助记符程序清单。【例7.1】用数据运算指令,对两个16位数做加法运算。这两个数从地址10050H开始连续存放,低位在小地址一端,结果放在这两个数之后。(1)分析题目:它是一个16位数相加的问题。在用加法指令时,必须要考虑低8位和低8位相加后产生的进位问题。2023/2/54/412023/2/55/41(2)根据86系列指令系统,可以直接对累加器AX做字操作,但在低位相加后,会影响标志寄存器的进位CF,所以,要用带进位的加法指令。(3)绘制程序流程图,如右图所示。简单程序框图(双字节相加)2023/2/56/41(4)内存空间分配:被加数、加数及和在内存的空间分配见下表内存地址内容10050H被加数低8位10051H被加数高8位10052H加数低8位10053H加数高8位10054H和的低8位10055H和的高8位双字节相加时的内存分配2023/2/57/4150H51H52H53H54H55H12H34HA1HBDHAX00H10H50H51H52H53H54H55HAX12H34HAXB3HF1HDIA1HBDH+=内存地址存储内容MOVAX,1000HMOVDS,AXMOVSI,50HMOVDI,52HMOVBX,54HSIDIBX50H51H52H53H54H55H12H34HA1HBDHB3HF1HBXB3HF1H低位在前,高位在后CLCXORAX,AXMOVAX,[SI]ADCAX,[DI]MOV[BX],AXHLT设SI=3412HDI=BDA1H内存分配示意程序详细注释见下页

2023/2/58/41(5)编制的程序如下:MOV

AX,1000H

MOV

DS,AX;DS=1000H

MOV

SI,50H;被加数指针SI=50H

MOV

DI,52H;加数指针DI=52H

MOV

BX,54H;和的指针BX=54H

CLC;

清CF

XOR

AX,AX;清AX异或

MOV

AX,[SI];取一个字到AX

ADC

AX,[DI];AX←AX+[DI]+CF

MOV[BX],AX;存一个字到[BX]HLT;暂停查看程序问题:该程序能否简化?如何简化?2023/2/59/41简化的程序:MOV

AX,1000H

MOV

DS,AX;DS=1000H

MOV

AX,[50H];取被加数到AXADC

AX,[52H];AX←被加数+加数MOV[54H],AX;存和数到[54H]HLT;暂停2023/2/510/41

【例7.2】将内存(10050)单元的内容(7AH)拆成两段,每段4位,并将它们分别存入内存(10051)和(10052)单元。即(10050)单元中的低4位放入(10051)的低4位,(10050)单元中的高4位放入(10052)的低4位,而(10051)和(10052)的高4位均为零。(1)分析题目:这个题目提出的任务在十六进制显示及二、十进制计算中常遇到的.现在假设内存(10050)中放着7AH,则题目要求就是把7AH拆成07H和0AH两部分,并把0AH放在(10051)单元,07H放在(10052)单元。2023/2/511/41

在拆字时,想取得一个数的前4位和后4位可以用移位指令的方法,也可以用逻辑“与”一个0F0H(二进制为11110000)和逻辑“与”一个0FH(二进制为00001111)的办法。(2)根据指令系统中含有的指令,先取出该数用逻辑指令与上一个0FH,得到低4位,存入内存。再取出该数用移位指令逻辑右移SHR4次,取得高4位,存入内存即可。2023/2/512/41(3)绘制程序流程图,如图所示。(4)内存空间分配:把7AH拆成07H和0AH两部分,它们在内存空间的分配情况见下页表。拆字程序框图2023/2/513/41内存分配示意图10050H7AH7HAH0H10051H0H10052H拆开AH7AHAH7AHAH7AHAH7H内存地址内容10050H7AH10051H0AH10052H07H拆字程序的内存分配2023/2/514/41(5)编制的程序如下:MOVAX,1000HMOVDS,AX;DS=1000HMOVSI,50H;需拆字节的指针SI=50HMOVAL,[SI];取一个字节到AL中ANDAL,0FH;把AL的前4位清0MOV[SI+1],AL;把得到的后4位放到(10051)单元MOVAL,[SI];再取出需拆字节放到AL中MOVCL,4SHRAL,CL;逻辑右移四次,前4位补0MOV[SI+2],AL;放入(10052)单元查看程序2023/2/515/41[例3]编程计算1+2+3+4。MOVAX,0ADDAX

,1ADDAX

,2ADDAX

,3ADDAX

,4初始化:AX0开始

AXAX+1

AXAX+2结束

AXAX+3

AXAX+4分析:需要有一个暂存空间存放累加和,初值设置为0,之后依次累加。2023/2/516/41练习:

将数据1A2BH,1200H,339AH,1200H分别存入相邻的内存单元中,然后将前三个数相加并减去第四个数,最后将结果传递到相近的内存单元中。7.3分支程序2023/2/517/41分支程序是利用条件转移指令实现程序执行次序改变的一种程序结构形式,即当程序执行到某一指令后,根据某个条件是否满足,分别执行不同的指令序列。一般来说,分支程序经常是先用比较指令或数据操作及位检测指令等来改变标志寄存器各个标志位。然后用条件转移指令进行分支。分支程序执行完后可以立即结束,也可以转到公共点结束。分支程序可以再分支。程序框图:在绘制程序流程图时,需用菱形判断框,表示判定条件。在绘制好流程图编写助记符程序时,建议先按上下流程线写,写完上下流程线上的各框环节后,再写分支部分里的框框。2023/2/518/41

【例7.3】求AX累加器和BX寄存器中两个无符号数之差的绝对值,结果放在内存(2800)单元中。(1)分析题目:此题目中,AX累加器和BX寄存器中的数是不知道的。对两个不知大小的数相减并求绝对值,显然应该先解决哪一个值稍大些,然后再用大数减小数的方法,才可求得绝对值。2023/2/519/41(2)根据指令系统中的比较指令,编出判断大小的环节,即可解决问题,下图即为该例题的程序流程图。求绝对值程序流程图JC=JumpifCarry当运算产生进位标志时,即CF=1时,跳转到目标程序处。(3)根据流程图编制程序如下:

CLC;清除CF

SUB

AX,BX

JC

AA;CF=1转AA去执行(即AX<BX时转移

MOV

DI,2800H;结果指针DI=2800H

MOV[DI],AX;结果送到2800H和2801H单元

HLT;暂停AA:

SUB

BX,AX;BX←BX-AX

MOV

DI,2800H

MOV[DI],BX

HLTSUBBX,AX2023/2/520/41

问题:这段程序有无错误?如果有错,如何改正?CMP

AX,BXSUB

AX,BX2023/2/521/41【例7.4】编一个程序,从外设71H号中取一个数M,判断其值是否在10和20之间,即10≤M<20。如果M≥20H,则送0FFH给外设73H;如果M<10,则送00H给外设73H;如果10≤M<20,则送88H给外设73H。(1)分析题目:根据题意,这是一个需要两次判断M大小的问题。先判M是否大于10,再判M是否大于20。2023/2/522/41(2)根据解决问题的思路,先画出程序流程图,如图。

从图的程序流程图看,两个分支都要“回归”原程序。判断M的两分支流程图2023/2/523/41

(3)编制的程序如下:START:IN

AL,71H;将71H端口的字节读入AL

CLC;清除CF

CMP

AL,10;将AL的内容和10相比较

JC

LP1;小于10转LP1

CMP

AL,20;将AL的内容和20相比较

JC

LP2;10≤AL<20转LP2

MOV

BL,0FFH;将0FFH送入BL寄存器LP3:OUT

73H,BL;将0FFH输出到73H端口

HLT;暂停LP1:MOV

BL,00

JMP

LP3LP2:MOV

BL,88H

JMP

LP3问题:这段程序有无错误?如果有错,如何改正?MOVBL,ALBLBLALALALAL;无条件转移START:IN

AL,71H;将71H端口的字节读入ALMOVBL,AL

CLC;清除CF

CMP

BL,10;将BL的内容和10相比较

JC

LP1;小于10转LP1

CMP

BL,20;将BL的内容和20相比较

JC

LP2;10≤BL<20转LP2

MOV

AL,0FFH;将0FFH送入AL寄存器LP3:OUT

73H,AL;将0FFH输出到73H端口

HLT;暂停LP1:MOV

AL,00

JMP

LP3LP2:MOV

AL,88H

JMP

LP32023/2/524/412023/2/525/41编一程序段,完成符号函数:

1 X>0(-128≤X≤127)Y= 0 X=0 -1 X<0

假设X的值存放在DATA1中,

Y的值存放在DATA2中。练习2023/2/526/41练习题程序如下:START:MOVAL,DATA1 ANDAL,AL JGEBIGR MOVAL,0FFH MOVDATA2,AL;X<0,-1送DATA2 HLTBIGR:JEEQUL MOVAL,1 MOVDATA2,AL;X>0,+1送DATA2 HLTEQUL:MOVDATA2,AL;X=0,0送DATA2 HLT2023/2/527/41读程序,问:本段程序的执行结果是什么?

BEGIN:IN

AL,5FH

TEST

AL,80H

JZ

BRCH1

MOV

AH,0

JMP

STOPBRCH1:MOV

AH,0FFH

STOP:HLT;将5FH端口的字节读入AL;如果AL的最高位为1,则ZF=0,否则ZF=1;当结果为零(即ZF=1)时,跳转至BRCH1;将立即数零送AH;无条件转移至STOP;将0FFH送AH

;暂停当AL的最高位为1时,AH=0;当AL的最高位为0时,AH=0FFH。2023/2/528/41

双分支程序设计

实现双分支程序设计要完成以下几项工作:

1.产生条件:主要用“比较”、“测试”等指令产生条件;

2.测试条件、定向转移:用条件转移指令完成;

3.设置执行标志(标号):给执行程序段定义地址标号。7.4循环程序2023/2/529/41循环程序是强制CPU重复执行某一指令序列(程序段)的一种程序结构形式。循环结构程序缩短了程序的长度、减少了占用的内存空间。循环程序并不简化程序执行过程,相反,由于增加了一些循环控制等环节,总的程序执行语句和时间会有所增加。循环程序一般由4部分组成:初始化、循环体、循环控制和循环结束处理。循环程序分为单循环和多重循环,两重以上循环称为多重循环。内外循环不能交叉。2023/2/530/417.4循环程序循环程序各部分的内容(1)初始化

建立循环次数计数器,设定变量和存放数据的内存地址指针(常用间址方式)的初值等。(2)循环体

实现程序功能的、被重复执行的指令序列。(3)循环控制

修改变量和地址指针,为下一次循环做准备;修改循环计数器或者判断循环条件是否满足,满足则继续循环,否则结束循环。(4)结束处理

它主要用来分析和存放程序的结果。2023/2/531/41循环控制方式有多种,如计数控制、条件控制等。计数控制事先已知循环次数,每次循环加或减计数,通过对循环次数的判定来达到控制循环的目的;条件控制事先不知循环次数,通过判定某种条件的真假来达到控制循环的目的。不管哪一种控制循环方式,最终都是要达到控制循环的目的。若考虑不周,会造成死循环,对这一点要注意。循环可以用跳转语句实现,如JMP,JZ等;也可以用专用循环控制语句实现,如LOOP、LOOPE/LOOPZ、LOOPNE/LOOPNZ。【例7.5】求两个多字节数之和。这两个数在10050H地址开始的内存单元中,连续存放,低位在小地址一端,结果放在这两个数之后。设这两个多字节数均为8个字节长。

程序流程图如右图所示。2023/2/532/41(1)分析题目:这是一个重复累加内存单元中数的问题,因此可以用循环程序形式解决。因为86系列指令系统可以16位处理,所以,循环次数是4次。2023/2/533/4112…57434…1存储器SI10050DI10058++++BX100605598…单击2023/2/534/41(3)编制的程序如下:START:MOV

AX,1000H

MOV

DS,AX;DS=1000H

MOV

SI,50H;第一个数指针SI=50H

MOV

DI,58H;第二个数指针DI=58H

MOV

BX,60H;结果指针BX=60H

MOV

CX,4;循环次数CX=4

CLC;清进位CF=0AA:MOV

AX,[SI];取一个字到AX

下页续2023/2/535/41

ADC

AX,[DI];AX←AX+[DI]+CF

MOV[BX],AX;存一个字到[BX]

PUSHF;保护进位CF

ADD

SI,2;修改第一个数的地址指针SI←SI+2

ADD

DI,2;修改第二个数的地址指针DI←DI+2

ADD

BX,2;修改结果指针BX←BX+2

POPF;恢复标志寄存器

LOOP

AA;CX←CX-1,若CX≠0转AA

HLT;CX=0,暂停结束2023/2/536/41

【例7.6】要求设计一个软件延时程序,延时时间约1ms左右。(1)分析题目:此题是想让计算机做一些无用的操作,来拖延时间。从指令手册中查得各条指令所需的时间节拍,但一般一条指令执行时间只有几个时钟周期,亦即只有几个微秒,为了能用较少的指令来编较长时间的延时,采用循环程序结构.2023/2/537/41(2)程序流程图如图所示。延时的时间主要取决于循环体及循环次数。PUSHF和POPF指令分别为10和8个时钟节拍,LOOPBX指令为3.4个时钟节拍,即此循环体需要用10+8+3.4=21.4拍,而每个时钟节拍是根据此系统的晶振频率而定的。假设此系统用的是8MHz的晶振,则每个时钟节拍需要0.125μs,因此可以根据下列公式算出循环次数:

X=延时时间/一次循环时间=1ms/21.4×0.125μs≈374次换算成十六进制数为176H。2023/2/538/41延时1ms的程序流程图延时1ms的程序流程图2023/2/539/41(3)编制的程序如下:START:MOV

CX,176H;初始化,设定循环次数CX=374LP1:PUSHF;循环体

POPF

LOOP

LP1;CX←CX-1,若CX≠0转

HLT;暂停对于上例,如果想再延长1000倍时间(即延时1s),可以采用双循环的方法,如图所示的程序流程图。对应的程序如下:2023/2/540/41

MOV

BX,3E8H;BX←1000LP2:MOVCX,176HLP1:PUSHF

POPF延时1ms程序段

LOOPLP1

DEC

BX;BX←BX-1

JNZ

LP2;ZF=0时,转至LP2,即BX≠0时转

HLT;暂停此程序中内循环是1ms时间,而在外循环中的两条控制指令DEC和JNZ所对应的时钟节拍分别为2个和4个,一共只需0.75μs,与1ms比较极短,所以在外循环里忽略不计了,外循环的循环初值仍设为1000次,对应的十六进制为3E8H。例设AX寄存器中有一个16位二进制数,编一程序,统计AX中‘1’的个数,统计结果送CX中。该程序可用固定次数循环和条件判断两种方法实现。条件判断法编制程序如下:START:MOVCX,0LOOP:SUB AX,0 JZ STP SAL AX,1 JNC NOD INC CXNOD:JMP LOOPSTP: HLT2023/2/541/41固定次数循环法,循环次数为16次,程序如下:其中:CX中存放循环次数,BX中存放“1”的个数.

MOVCX,16MOVBX,0AA:SHLAX,1JCYYJMPPPYY:INCBXPP:LOOPAAHLT例:计算S=1+2+3+……+100的和值并将其存入数据段[2000H]单元.2023/2/542/41程序如下:

MOVCX,0064H

MOVAL,0MOVBL,1AA:ADDAL,BLINCBLLOOPAAMOV[2000H],ALHLT例:读程序,(1)本程序实现什么功能?(2)结果在哪里?2023/2/543/41START:IN

AL,20H

MOV

BL,AL

IN

AL,30H

MOV

CL,AL

MOV

AX,0ADLOP:ADD

AL,BL

ADC

AH,0

DEC

CL

JNZ

ADLOP

HLT

;将20H端口的字节读入AL;AL中的8位字节送BL;将30H端口的字节读入AL;AL中的8位字节送CL;立即数0送AX;AL与BL的内容相加,结果放AL;AH的内容与立即数0以及CF相加;CL内容减1,结果放CL;当结果不为零时,执行ADLOP;暂停20H与30H端口的内容相乘,结果放在AX中447.5子程序和库为了程序共享或模块化设计的需要,可以把一段公共语句序列设计成子程序或宏指令的形式。45

当把一段可共享的语句序列组织成子程序后,一旦需要实现该功能,就由调用程序调用之,当子程序执行结束后再返回到主程序继续执行。7.5.1子程序的定义

主程序子程序

主子程序关系示意图①②③④46定义子程序的一般格式在汇编语言中用过程定义伪指令定义子程序。 过程名 PROC【类型】 …

过程名 ENDP477.5.1子程序的定义“子程序名”必须是一个合法的标识符,并前后二者要一致;PROC和ENDP必须是成对出现的关键字,表示子程序定义开始和结束;子程序的类型有近(NEAR)、远(FAR)之分,其缺省的类型是近类型;NEAR类型的子程序只能被与其同段的程序所调用,FAR类型的子程序可被不同段的程序所调用;子程序至少要有一条返回指令。返回指令是子程序的出口语句,但它不一定是子程序的最后一条语句;子程序名有三个属性:段值、偏移量和类型。其段值和偏移量对应于子程序的入口地址,其类型就是该子程序的类型。48

调用子程序指令格式如下:

CALL子程序名/Reg/Mem子程序的调用指令分为近(near)调用和远(far)调用。如果被调用子程序的属性是近的,那么,CALL指令将产生一个近调用,它把该指令之后地址的偏移量(用一个字来表示的)压栈,把被调用子程序入口地址的偏移量送给指令指针寄存器IP即可实现执行程序的转移。7.2子程序的调用和返回指令49如果被调用子程序的属性是远的,那么,CALL指令将产生一个远调用。这时,调用指令不仅要把该指令之后地址的偏移量压进栈,而且也要把段寄存器CS的值压进栈。在此之后,再把被调用子程序入口地址的偏移量和段值分别送给IP和CS,这样完成了子程序的远调用操作。例如:

CALLDISPLAY ;DISPLAY是子程序名

CALLBX ;BX的内容是子程序的偏移量

CALLWORD1 ;WORD1是内存字变量,其值是子程序的偏移量501.子程序调用指令

CALL

格式:CALLDST

功能:调用子程序。执行时先把返回地址压入堆栈,再形成子程序入口地址,最后把控制权交给子程序。 说明:其中DST为子程序名或子程序入口地址,其目标地址的形成与JMP指令类似,可以有段内直接/间接调用、段间直接/间接调用之分,只是不能使用段内直接寻址方式的SHORT格式。51⑴段内调用这类调用指令实现同一段内的子程序调用,它只改变IP值,不改变CS值。执行操作:把返回地址(CALL之后的那条指令地址的偏移量部分(当前IP值))压入堆栈。根据与转移地址有关的寻址方式形成子程序入口地址的IP值。把控制无条件转向子程序,即执行CS:IP处的指令。52①段内直接调用:格式:CALLPROCEDURE或:CALLNEARPTRPROCEDURE功能:调用PROCEDURE子程序。执行时先把返回地址压入堆栈,再使IP=(IP)+disp16,最后把控制权交给子程序。说明:这种指令使用与转移地址有关的寻址方式中的段内直接寻址方式。例1.

设子程序A与CALL指令在同一段内,则调用A子程序的指令是:

CALLA或:CALLNEARPTRA53②段内间接调用: 格式:CALLREG/M

功能:调用子程序。执行时先把返回地址压入堆栈,再把指令指定的16位通用寄存器或内存单元的内容送给IP,最后把控制权交给子程序。说明:这种指令使用与转移地址有关的寻址方式中的段内间接寻址方式,指令指定的通用寄存器或内存单元中存放段内偏移量。54⑵段间调用

这类调用指令可以实现段间调用(FAR型调用),执行时即要改变IP值,也要改变CS值。55①段间直接调用:

格式:CALLFARPTRPROCEDURE

功能:调用PROCEDURE子程序。执行时先把返回地址(当前IP值和当前CS值)压入堆栈,再把指令中的偏移量部分送给IP,段基址部分送给CS,最后把控制权交给子程序。

说明:这种指令使用与转移地址有关的寻址方式中的段间直接寻址方式。

例3.

设子程序B与CALL指令不在同一段内,则段间直接调用B子程序的指令是:

CALLFARPTRB56②段间间接调用: 格式:CALLM

功能:调用子程序。执行时先把返回地址(当前IP值和当前CS值)压入堆栈,再把M的低字送给IP,高字送给CS,最后把控制权交给子程序。 说明:这种指令使用与转移地址有关的寻址方式中的段间间接寻址方式,其中M为内存的双字长地址指针,低字部分为16位的偏移量,高字部分为段基址。57

例4.

对于例3,若子程序B的入口地址(偏移量和段基址)放在变量VAR中,即可通过VAR实现段间间接调用。如下所示:

CALLDWORDPTRVAR ;从VAR变量中得到子程序B的入口地址实现调用 变量VAR的地址也可以通过寄存器间接寻址方式、基址变址寻址方式等存储器操作数寻址方式得到。

例.CALLDWORDPTR8[BX][DI] 58

当子程序执行完时,需要返回到调用它的程序之中。为了实现此功能,指令系统提供了一条专用的子程序返

温馨提示

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

评论

0/150

提交评论