微机原理与接口技术PPT电子课件教案-第04章 汇编语言程序设计.ppt_第1页
微机原理与接口技术PPT电子课件教案-第04章 汇编语言程序设计.ppt_第2页
微机原理与接口技术PPT电子课件教案-第04章 汇编语言程序设计.ppt_第3页
微机原理与接口技术PPT电子课件教案-第04章 汇编语言程序设计.ppt_第4页
微机原理与接口技术PPT电子课件教案-第04章 汇编语言程序设计.ppt_第5页
免费预览已结束,剩余83页可下载查看

下载本文档

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

文档简介

汇编语言程序设计,第 4 章,4.1 8086汇编语言程序格式 4.1.1 汇编语言程序上机 过程 4.1.2 汇编语言程序格式 4.1.3汇编语言语句格式 4.1.4 伪指令与伪操作,4.2 汇编语言程序设计 4.2.1 顺序程序设计 4.2.2 分支程序设计 4.2.3 循环程序设计 4.2.4 子程序设计,汇编程序(翻译程序),源程序的编译程序,汇编程序,汇编语言源程序,机器语言目标程序,汇编源程序需翻译成机器语言,变成可执行文件,机器才能执行,这个翻译过程叫汇编。 高级语言中称该过程为“解释”或“编译”。执行翻译的程序称为“汇编程序”。,汇编语言的处理过程: (1)编写汇编语言源程序,生成扩展名为asm的汇编源源文件。 (2)对汇编源程序进行编译,把asm文件汇编成obj文件。 (3)用link程序对目标文件进行连接,生成exe文件 。,4.1,8086汇编语言基础,1)效率低(与人们描述计算过程的需要差距大); 2)机器硬件的具体结构联系过于紧密在一种结构的机器上开发 的程序极难移植到另一种不同结构的机器上去。,4.1,8086汇编语言基础,汇编语言进行程序设计的优点,1)充分利用机器的硬件功能和结构特点,加快程序的执行速度, 减少目标程序所占用的存储空间; 2)用来编写实时控制程序、实时通信程序,有时也用来编制某些 系统软件程序。,汇编语言进行程序设计缺点,4.1.2 汇编语言源程序格式,汇编语言源程序通常由一个或几个程序模块组成,每个模块一般由3个(或4个)逻辑段组成: 数据段存放数据、变量 (附加数据段存放数据、变量) 堆栈段堆栈区域 代码段存放程序指令,0000:03ff,环境与代码运行,ffff:0,堆栈段,数据段,代码段,cs:ip,ds,ss:sp,系统起始运行程序,中断向量区 (系统专用),栈底,最多4个活动段,分段结构,es,一个基本的汇编语言程序框架如下: stack segment para stack db 100 dup(stack) stack ends data segment data ends code segment assume cs:code, ds:data, es:data, ss:stack start: mov ax, data mov ds, ax mov es, ax mov al, 4ch int 21h code ends end start,堆栈段,数据段,代码段,真指令,汇编语言语句格式,在8086汇编中使用的语句可以分成2种类型,这类指令能够产生目标代码,是cpu可以执行的能够完成特定功能的语句,主要由机器指令组成。在汇编时一条指令语句被翻译成对应的机器码,对应着特定的操作。,伪指令语句是为汇编程序和连接程序提供一些必要控制的管理性语句,它不产生目标代码,仅仅在汇编过程中告诉汇编程序应如何汇编,如何定义变量、分配存储单元以及指示程序开始和结束等。指示性语句无机器码指令与其相对应。,4.1.1,注意: 指令性语句汇编时生成机器码; 指示性语句汇编时不生成机器码。,汇编语言源程序中的语句可以由四项组成,格式如下: 名字 操作码 操作数 ;注释,汇编语言语句格式,4.1.1,(2)操作码可以是指令、伪指令或宏指令的助记符。 (3)操作数字段是操作符的操作对象。 (4)注释字段是以“;”开头的说明部分,可以用英文或者中文书写。,1.汇编语言格式,(1)名字项是程序设计人员自己定义的符号, 用于代表内存单元的地址,表示本条语句的符号地址。一般来说,名字可以是标号和变量,统称为标识符。,指令性语句的格式为: 标号: 指令助记符 目的操作数,源操作数 ; 注释 指示性语句的格式为: 名字 伪指令 操作数1, 操作数2, ,操作数n ; 注释,汇编语言的一个实例: hello.asm(例022) stack segment para stack stack dw 100 dup(0) stack ends data segment hello db hello, world!,0dh,0ah,$ data ends prog segment assume cs:prog,ds:data,ss:stack start: mov ax,data mov ds,ax lea dx,hello ;取字符串首地址 mov ah,9 int 21h ;显示字符串 mov ah,4ch int 21h ;退回dos prog ends end start,名字,标号,1. 名字,标号指令的符号地址,用来代表指令在存储器中的地址。只能出现 在指令性语句中,标号后应加上冒号。 变量段、过程、变量的名字,用来代表它们在存储器中的地址。只 能出现在指示性语句中,名字后不加冒号。,操作码可以是指令、伪指令或宏指令的助记符。对于指令,汇编程序将其翻译成机器语言指令。 对于伪操作,汇编程序根据其功能进行处理。对于宏指令,则将根据其定义展开,转换成对应的代码。,2. 操作码,操作数的形式 :常量、标号/名字、变量及表达式。 1.常量 二进制数,以b结尾。如01001101b。 十进制数,如85。 十六进制数,以h结尾。第1个数字为a-f时,前面应加0,如0f160h。 字符串:用引号括起来的1个或多个字符。 如error!, a,汇编时被翻译成对应的ascii码45h,52h,52h,4fh,52h,21h, 61h。,3. 操作数,变量即内存中的存储单元或数据区。 变量名是存储单元(数据区)的符号地址 或 名字。 变量也有三个属性: 段地址变量所在段的段地址 偏移量变量单元地址与段首地址之间的位移量。 类 型有byte、word 、dword三种之一。 变量在程序中作为存储器操作数被引用。,3.变量,如 start : mov ax, data,ptr,4.表达式,表达式是常数、寄存器、标号、变量与运算符的组合。 有数字表达式和地址表达式两种。 汇编时按优先规则对表达式进行计算,计算出具体的数值或地址。运行时不能改变。 表达式中的运算符有6类:算术、逻辑、关系、取地址、属性、杂类。,如 start : mov ax, 16*8+table,用于数字表达式, 例: mov ax,4*1024 汇编后的形式为: mov ax,4096 用于地址表达式, 例: lea si,tab+3 若tab的偏移地址为1000h,则汇编后的形式为: lea si,1003h,1)算术运算符 +、-、*、/,mod,逻辑运算符只能用于数字表达式中。 例: mov cl,36h and 0fh 经汇编后:mov cl,06h 注意: 不要把逻辑运算符与逻辑运算指令混淆: 例:and ax, 3fc0h and 0ff00h 汇编后源操作数被翻译为:3f00h,所以上述指令与 and ax, 3f00h等价。,2)逻辑运算符 and、or、xor、not 移位运算符shl、shr,关系运算的结果是一个逻辑值:真或假 关系为真,结果为全1 关系为假,结果为全0 例: mov bx, port gt 300h 若port的值大于300h为真,则汇编后为: mov bx, 0ffffh 若为假,则汇编后为: mov bx, 0,3)关系运算符eq、ne、lt、gt、le、ge,取地址运算符seg、offset seg: 取变量/标号的段地址 offset:取变量/标号的偏移地址 例:var db 12h mov bx,offset var ;取变量var的偏移地址 mov ax,seg var ;取变量var的段地址 注意: 下面两条指令的异同: mov bx, offset var lea bx, var offset只能取静态的偏移地址; lea指令即可取静态的偏移地址,也可取动态的偏移地址。,4)数值回送操作符,type 取变量的类型(1,2,4) length 取所定义变量的长度 (即变量中元素的个数) size 取所定义存储区的字节数 (=type * length) 例:var dw 1,2,3,4,5 则 type var = 2 length var = 5 size var = 10,取值运算符type、length、size,5)属性操作符,ptr,short,this,high,low,highword,lowword ptr 用来指定地址操作数的类型。 格式: ptr 类型byte, word, dword和 near, far ,short byte、word、dword 用于描述数据存储单元(变量)地址 near、far (short ?) 用于描述转移、调用的目的地址,例:mov byte ptrdi,0 ;字节类型 mov word ptrdi,0 ;字类型 mov di,0b5h ;类型不定 ptr也可用来进行强制类型转换 例:str1 dw ? ;str1定义为字类型 mov ax,str1 ;合法 mov al,str1 ;非法 mov al,byte ptr str1 ;合法,short: 用来修饰jmp指令中转向地址的属性,指出转向地址是在下一条指令地址的-128+127个字节范围之内。 this: 格式为: this attribute 或 type 它可以象ptr一样建立一个指定类型(byte、word或dword)的或指定距离(near或far)的地址操作数。该操作数的段地址和偏移地址与下一个存储单元地址相同。 例如: first_type equ this byte word_table dw 100 dup(?),此时first_byte的偏移地址值和word_table完全相同,但它是字节类型的,而word_table则是字类型的。,又如: start equ this far mov cx,l00 mov指令有一个far属性的地址start,这就允许其它段的jmp指令直接跳转到start来。 high和low; highword 和lowword 称为字节分离操作符字节。它接收一个数或地址表达式,high取其高位字节,low取其低位字节。 const equ 0abcdh mov ah, high const 则汇编完成 mov ah, 0abh,6)注释项,注释项用来说明一段程序或一条或几条指令的功能,它是可有可无的。但是,对于汇编语言程序来说,注释项的作用是很明显的,它可以使程序易于被读懂,因此,编制程序必须写好注释。,四、 伪指令与伪操作,数据定义 伪指令 符号定义 伪指令 段定义和段寄存器指定伪指令 过程定义 伪指令 结束 伪指令,由汇编程序执行的指令,它本身不被汇编成机器指令。常用的伪指令有:,名字 伪指令 操作数1, 操作数2, ,操作数n ; 注释,把一个表达式用一个符号表示,以后凡出现该表达式的地方都可用这个符号表示。类似于c语言中的#define。 符号定义伪指令有两种: equ =,用equ定义的符号未清除前,不能重新定义。清除equ定义可用purge伪指令。 用”=”定义的符号可在任何时候进行重定义。 二者均不占用存储空间,仅是给符号赋值,(1)定义常量的伪指令,例:five equ 5 count equ cx ten equ 10 dist = byte ptrsi+bp goto = jmp mov ax, ten mov cx, count add dist, five dist = word ptrsi+bp+1 add dist, ax goto label,定义,引用,(2)数据定义伪指令,用于定义变量,即内存单元或数据区。数据定义伪指令的格式为: 变量名 数据定义伪指令 操作数,操作数, 常用的数据定义伪指令有如下几种: db 定义字节 dw 定义字 dd 定义双字 操作数可以是常数、变量或表达式,例1: data_b db 10,5,10h data_w dw 100h,-4 data_d dd 0fffbh 汇编后的内存分配情况 如右图所示。,05h,10h,00h,01h,fch,ffh,fbh,ffh,00h,00h,0ah,data_b,data_w,data_d,10,5,10h,100h,-4,0fffbh,例2:操作数可以是字符串,例如 str db hello 汇编后的情况如图:,str,h,e,l,l,o,注意:下面两个定义的不同之处: db ab ;41h在低字节,42h在高字节(先a后b) dw ab ;42h在低字节,41h在高字节(先b后a),48h,45h,4ch,4ch,4fh,操作数?用来保留存储空间,但不存入数据. 例3:abc db 0,1,2,3,4,ok,$ rsv dw ?,?,?,?,?,?,?,? 复制操作符dup: 重复的数据可以使用复制操作符dup,如上面rsv亦可写成: rsv dw 8 dup(?) array db 2 dup(0,1,2,?) 若操作数中若使用$,则表示的是地址计数器的当前值。,例4: table db 10 dup(?) buffer dw table,$+3 设table的偏移地址为0080h,则汇编后如下图所示:,buffer,0080h,80h,table,008ah 008bh 008ch 008dh,. . .,8dh,00h,00h,0089h,10 bytes,$,$+3,(3)定义程序开始和结束的伪指令,在源程序开始处可以用name或title为模块取名字。 name name module_name 汇编程序将以给出的“模块名”作为模块的名字。 title title text title伪指令可指定每一页上打印的标题。同时,若程序中没有name伪指令,则汇编程序将用text 中的前6个字符作为模块名。text最多可有60个字符。 若程序中既无name又无title伪指令,则将用源程序名作为模块名。所以name及title伪指令并不是必要的,但一般常使用title,以便在列表文件中能打印出标题来。,汇编结束伪指令,end的使用 end 第一条指令的标号或主过程名 作用:表示汇编到此结束 位于源程序的最后一行。end之后的语句不会被汇编程序翻译,(4)指令集选择伪指令,汇编语言选择指令系统 8086;选择8086指令系统 286;选择80286指令系统 286p ;选择保护方式下的80286指令系统,(5)地址计数器与对准伪操作,地址计数器$ 把它称为程序计数器。表示位置计数器的当前值,它可以在数值表达式中使用。在程序中,“$”出现在表达式里,它的值为程序下一个所能分配的存储单元的偏移地址。,sortd segment array db 25,46,3,75,5 count equ $ - array sortd ends array的偏移地址值为0000h $ 的偏移地址值为0005h count = 0005h 0000h = 5,array,0000h,0005h,$,地址对准器伪指令org,下一个地址变量的偏移地址值由org确定 data segment org 2 var1 db 2,3,4 org $ + 3 var2 dw 1234h data ends,var1,$ + 3 var2,0002h,0008h,$,org是起始位置设定伪指令,用来指出源程序或数据块的起点。利用org伪指令可以改变位置计数器的值。,even伪操作使下一个字节地址成为偶数。一个字的地址最好从偶地址开始,所以对于字数组为保证其从偶地址开始,可以在它前面用even伪操作来达到此目的。例如: data_seg segment even word_array dw 100 dup(?) data_seg ends,对准伪指令,(七)过程定义伪指令,proc far 、endp 远过程定义伪指令 proc near、endp 近过程定义伪指令,过程名 proc far(near) 过程指令集合 ret 过程名 endp 注:过程定义必须在代码段内 proc far 为定义远过程 proc near 为定义近过程,(八) 段定义伪指令,汇编语言程序是按段来组织程序和数据的。 和存储器的物理段相对应,汇编语言程序中的段称为逻辑段。汇编连接后被映射到物理段中。 3/4类段:代码(程序)、数据/附加数据、堆栈 段定义伪指令:segment、ends、assume、org 定义一个段的基本格式: 段名 segment 定位类型组合方式类别 段名 ends,这两个伪指令总是成对出现,二者前面的段名应一致。segment说明了一个段的开始,ends说明了一个段的结束。 对数据段和堆栈段,段中的语句一般是变量定义。 对代码段则是指令语句。 如: data segment data ends,segment和ends伪指令,assume伪指令,在代码段中,还必须明确段和段寄存器的关系,这由assume语句来指定。如 assume cs:code,ds:data,es:data,ss:stack 语句中的code和data为段名。 这个语句说明: (1) cs将指向名字为code的代码段 (2) ds和es将指向名字为data的数据段 (3) ss将指向名字为stack的堆栈段,注意: assume伪指令只是告知汇编程序有关段寄存器与段的关系,并没有给段寄存器赋予实际的初值。故下面的语句 mov ax,data mov ds,ax mov es,ax mov ax,stack mov ss,ax 将段基址装入段寄存器。如果程序中用到堆栈段,则ss也需装入实际的初值。 代码段基地址不需要程序员装入cs寄存器,而由操作系统(os)负责装入。,segment语句后可以带有可选参数,用以规定逻辑段的其他一些属性。它的格式为:,1) 定位类型 说明如何确定逻辑段的边界。有4种: para(paragraph): 逻辑段从一个节 (16个字节) 的边界开始。即段的起始地址应能被16整除, 或这说段起始物理地址应为0h。默认类型 byte : 逻辑段从字节边界开始,即段可以从任何地址开始。 word : 逻辑段从字边界开始。即段的起始地址必须是偶数。 page : 逻辑段从页边界开始。256字节称为一页,故段的起始物理地址应为00h。,也即:page(页边界) - 能被256除;para(段边界) -能被16除; word(字边界) - (能被2除);byte (字节边界),段名 segment 定位类型 组合类型 类别,2) 组合类型 说明程序连接时的段合并方式,共6种: private :该段为私有段,连接时将不与其它模块中的同名段合并 public: 所有此类型的同名段组合成一个逻辑段,公用一个段地址,运行时装入同一个物理段中。 common : 所有此类型的同名段具有相同的起始地址(覆盖),共享相同的存储区域。 at : 按绝对地址定位,段地址就是表达式的值。 stack : 专用于说明堆栈段,组合方式同public memory :置于地址最高处,多个时取第一个,其余作为common,3) 类别 用单引号 括起来的字符串。所有同类别的段被安排在连续的存储区域中。 如:在模块1中有段定义: seg1 segment para stack stack seg1 ends 在模块2中有段定义: seg2 segment para stack stack seg2 ends 则连接时这两个段被安排在一起。,1-定义问题,分析问题 2-建立数学模型,确定算法 3-画出程序框图(流程图) 4-分配内存工作单元和寄存器 5-根据框图,编写源程序 6-上机运行、调试程序。 将源程序存成.asm文件; 对源程序汇编,生成.obj目标文件; 把.obj文件连接成.exe执行文件。,4.2 汇编语言程序设计,汇编语言上机过程:,y,y,y,n,n,n,有错 ?,有错 ?,有错 ?,结束,汇 编,输入(修改)源程序,连 接,运 行,查 错,开始,用edit,notepad等任何文本编辑器。源程序存为.asm文件,用masm宏汇编程序进行汇编。 汇编后生成.obj目标文件。 命令格式:masm ;,用link连接程序进行连接。 连接后生成.exe可执行文件。 命令格式:link ;,用td、debug等调试程序进行调试。 命令格式:td ,程序设计是把解决实际问题的方法转化为程序。由于实际问题有简单与复杂之分,因此程序设计就需要根据解决问题的思路,运用一些基本的程序设计方法设计出解决不同问题的程序来。在汇编程序设计过程中,首先对要解决的问题的过程进行具体的描述,这也是编程的准备阶段,对于较小的程序可以使用程序流程图。对于较大的程序可以采用模块化程序设计方法。无论采用流程图还是模块化的方法设计都要使用程序设计的基本程序结构来表现出来。基本的程序结构包括顺序结构、分支结构、循环结构及子程序结构。由于不同的问题可采用不同结构设计,因此需要对各种结构形式有所了解,才能找到解决某一问题的最佳程序结构形式。 ,顺序结构是一种最简单的程序设计结构形式。采用这种结构只能完成简单的任务程序设计。顺序结构在任何结构的程序中都会出现,因此说它是基础。下面举一个顺序结构的程序设计例子,要求完成表达式所规定的操作: y=x1+x2+x3。首先分析程序设计方法: 表达式y=x1+x2+x3的计算过程可采用顺序执行的方法来完成: 首先读入数据x1、x2、x3;其次计算x1、 x2、 x3的和;最后保存结果到指定变量y中。 根据计算步骤编写汇编语言程序:利用伪指令确定存储器的分配,将x1、x2、x3定义为字变量;按照汇编语言源程序结构要求编写源程序。,顺序程序设计,程序如下: (例006) stack segment para stack dw 64h dup(?) stack ends data1 segment x dw 5 y dw 6 z dw 7 w dw ? data1 ends code segment assume cs:code,ss:stack,ds:data1 start: mov ax,data1 mov ds,ax mov ax,x add ax,y adc ax,z mov w,ax mov ax, 4c00h int 21h code ends end start,顺序程序设计,可以看出,上面的源程序是由数据段和代码段两部分组成的。在数据段定义了x、y、z为自变量,在运行时应填入具体数值。代码段确定了各段与段寄存器的关系,并且以计算机的基本操作指令按顺序执行的结构形式将计算机操作过程进行描述,从而完成程序设计的最初阶段任务。一个源程序的编写过程还说明不了程序的正确性,必须经过上机调试,才能验证设计的程序是否符合要求。,顺序程序设计,顺序程序设计,用查表法求z=x3 定义数据段 data segment table db 0, 1, 8, 27, 64, 125, 216 xval db 6 yval db ? data ends,table,定义堆栈段 stack segment db 100 dup ( ?) stack ends,顺序程序设计,定义代码段 code segment assume cs:code, ds:data ,ss:stack start proc far push ds mov ax, 0 push ax mov ax, data mov ds, ax lea bx, table mov al, xval xlat mov yval, al ret start endp code ends end start,循环结构程序设计针对的是处理一些重复进行的过程的操作。采用循环结构设计的程序,其长度缩短了,不仅节省了内存,也使得程序的可读性大大提高。使用循环结构形式设计程序时, 通常将循环程序划分三个部分: 循环的初始化部分:主要为循环所需的变量赋初值。 循环体:程序所要完成的主要工作部分,这一部分的内容是由所要处理的问题来确定的,这一部分的执行结果可能影响到循环是否继续进行。 循环控制部分:这一部分主要是以条件表达式的结果作为是否结束循环的条件。在事先知道了循环次数的情况下,可采用循环计数控制循环的结束;在事先不知道循环次数的情况下,多采用结果及给定特征作为条件来控制循环的结束。 下图 可以帮助我们很好地理解循环结构程序。,循环程序设计,图 循环程序结构 (a) 单循环结构; (b) 双循环结构,在编写程序之前要对解决的问题进行分析: 首先确定程序采用循环结构完成数据搬家操作。 定义数据单元。 按顺序将源数据逐一搬家(该步骤要求修改源数据地址、目的数据地址及搬家次数)。 搬家程序的控制是以变化的数据个数作为条件。,循环程序设计,下面举例说明这类指令的功能及应用。 要求将偏移地址为1000h开始存放的100个字节的数据传送到偏移地址为1500h开始的连续内存区。假设它们的段地址存放在ds中,段地址为2000h。,程序如下: mov ax, 2000h mov ds, ax mov si, 1000h mov di, 1500h mov cx, 100 loop: mov al, si mov di, al inc si inc di dec cx jnz loop hlt,根据循环程序的嵌套层数不同,可以将循环程序的结构分成单循环、双循环和多重循环。,要求将内存中以areay1为首地址的100个字节数据搬移到以areay2为首地址的内存中去。 程序如下: mov si, offset areay1 mov di,offset areay2 mov cx, 100 again: mov al, si mov di, al inc si inc di dec cx jnz again hlt,将100个字符的字符串从内存的buffer1搬移到内存的buffer2中去。 程序如下: mov si , offset buffer1 mov di, offfet buffer2 mov cx, 100 cld repe movs buffer1,buffer2 注意:上述程序中的buffer1应处于ds段中,而buffer2应处于es段中,循环程序设计,计算,和清0 ax 计数初值100 cx,(ax) = (ax) + (cx),(cx) = (cx) - 1,(cx) = 0,sum = (ax),y,n,流程图,循环程序设计,;数据段定义 data segment sum dw ? data ends;堆栈段定义 stack segment para stack dw 100 dup(?) stack ends ;代码段定义 code segment assume cs: code, ds: data, ss:stack main: mov ax,data mov ds,ax ; 主程序定义法 mov ax,0 ; 和清零,循环程序设计,mov cx,100 ; 赋计数初值 again: add ax, cx ; 累加 dec cx ; 计数器减 1 jnz again ; cx 不为零循环 mov sum,ax mov ah, 4ch ;dos 中断号送 ah int 21h ; int 21h 返回 code ends ; 结束代码段 end main ; 结束汇编,七段共阴led数码管显示,七段共阴led数码管显示,数据段定义 data segment val db 47531 ;待显示的数值,带小数点 disp equ 6000h ;第一个数的显示端口地址 tab db 0fch,60h,0dah,0f2h,66h;04 db 0b6h,03eh,0e0h,0feh,0e6h;59 tab1 db 0fdh,61h,0dbh,0f3h,67h;0.4. db 0b7h,03fh,0e1h,0ffh,0e7h;5.9. data ends,七段共阴led数码管显示,堆栈段定义 stack segment para stack stack dw 80 dup(?) stack ends 代码段定义 code segment assume cs:cdoe,ss:stack,ds:data stab:mov ax,data mov ds,ax ;标准写法 lea si,val ;si指向测试结果首址 cld ;df = 0,自动增量 lods byte ptr val ;取第一个数至al中 and al,0fh ;转换成十进制数,七段共阴led数码管显示,lea bx,tab ;表首址tab xlat tab ;查表 mov dx,disp ;dx为显示端口地址 out dx,al ;第一个端口 inc dx ;下一个端口地址 lods byte ptr val ;取带小数点的第二个数 and al,0fh lea bx,tab1 ;指向tab1 xlat tab1 out dx,al ;至第二个端口 inc dx inc si ;小数点已送显,七段共阴led数码管显示,mov cx,3 ;余下3个数未转换 lea bx,tab ;不带小数点 agn:lods byte ptr val and al,0fh xlat tab out dx,al inc dx loop agn mov ah,4ch ;完毕,返回dos int 21h code ends end stab,在解决某些实际问题时,解决问题的方法随着某些条件的不同而不同,将这种在不同条件下处理过程的操作编写出的程序称为分支程序。程序中所产生的分支是由条件转移指令来完成的。汇编语言提供了多种条件转移指令,可以根据使用不同的转移指令所产生的结果状态选择要转移的程序段,对问题进行处理。采用分支结构设计的程序,结构清晰、 易于阅读及调试。 下面是一个采用分支结构设计的程序例子,要求从键盘上输入字符,若为az,则将其转换为对应的ascii码并显示;若为0,则结束输入。,条件程序设计(分支结构程序设计),首先使用程序流程图将解决问题的思路描述出来,如图所示。 程序如下: abc1: mov ah, 01h; 置键盘输入并回显 int 21h ;系统功能调用 cmp al, 0 ; 输入字符与0比较 je abc2 ; 为零结束 cmp al, a ; 判断是否小于大写字母a jl abc1 ; 小于大写字母a返回重新输入 cmp al, z ; 判断是否大于大写字母z jg abc1 ; 大于大写字母z返回重新输入 mov dl, al ; 将al内容送dl,作为输入参数 mov ah, 02 ; 置显示输出 int 21h ; 将az的字符从显示器输出 abc2:mov ah, 4ch ; 带返回码结束int 21h int 21h ,条件程序设计,在汇编语言程序设计中,常常要使用多分支结构。多分支结构相当于一个多路开关,在程序设计中通常是根据某寄存器或某单元的内容进行程序转移。 在设计多分支转移程序时,如果分支太多,则平均转移速度太慢。如果用转移地址表实现多分支转移,则可以提高平均转移速度。多分支结构如图 所示。 ,条件程序设计,条件程序设计,实现表达式,波形图,条件程序设计,流程图,条件程序设计,数据段定义 data segment x db -3 y db ? data ends 堆栈段定义 stack segment para stack dw 100 dup(?) stack ends 代码段定义 code segment assume cs:code; ds:data main proc near push ds xor ax, ax push ax mov ax, data mov ds, ax ; 标准写法,条件程序设计,mov al, x cmp al, 0 jge biger ; x 大于等于 0 转 biger mov al, 0ffh ; -1的补码为ffh mov y, al ; y = -1 jmp next biger: je equl ; x 等于 0 转 equl mov al, 1 mov y, al ; y = 1 jmp next equl: mov y, al ; y = 0 next: ret main endp ; 结束过程 code ends ; 结束代码段 end main ; 结束汇编,子程序设计,子程序的概念 如果在一个程序中的多个地方、或多个程序中的多个地方用到了同一段程序,那么可以将这段程序抽取出来,存放在某一存储区域,每当需要执行

温馨提示

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

评论

0/150

提交评论