第四章+程序设计201509_第1页
第四章+程序设计201509_第2页
第四章+程序设计201509_第3页
第四章+程序设计201509_第4页
第四章+程序设计201509_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

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

文档简介

1、懒惰是很奇怪的东西,它使你以为那是安逸,是休息,是福气;但实际上它所给你的是无聊,是倦怠,是消沉;它剥夺你对前途的希望,割断你和别人之间的友情,使你心胸日渐狭窄,对人生也越来越怀疑。罗兰 第第4 4章章 汇编语言程序设计汇编语言程序设计mov ax,12hcall displayJmp 1234h 主要内容: 汇编程序(翻译程序)源程序的编译程序源程序的编译程序汇编程序汇编程序汇编语言汇编语言源程序源程序机器语言机器语言目标程序目标程序 汇编源程序需翻译成机器语言,变成可执行文件,机器才能执行,这个翻译过程叫汇编汇编。高级语言中称该过程为“解释”或“编译”。执行翻译的程序称为“汇编程序汇编程序

2、”。汇编语言程序设计与执行过程 输入汇编语言源程序 EDIT/NOTEPAD等 源文件 .ASM 汇编(编译) MASM /ASM等 目标文件 .OBJ 链接 LINK等 可执行文件 .EXE 调试 DEBUG/TD等 最终正确的程序.EXE 建立、编辑建立、编辑 汇编汇编 连接连接 运行运行 调试调试汇编语言源程序的结构 汇编语言源程序通常由一个或几个程序模块组成,每个模块一般由3个(或4个)功能段组成: 数据段数据段存放数据、变量存放数据、变量 ( (附加数据段附加数据段存放数据、变量存放数据、变量) ) 堆栈段堆栈段堆栈区域堆栈区域 代码段代码段存放程序指令存放程序指令 一个基本的汇编语

3、言程序框架如下: 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 堆栈段数据段代码段真指令0000:03FF环境与代码运行环境与代码运行FFFF:0堆栈段堆栈段数据段数据段代码段代码段CS:IPDSSS:SP系统起始运

4、行程序系统起始运行程序中断向量区中断向量区(系统专用)(系统专用)栈底最多4个活动段分段结构分段结构ES汇编语言源程序返回操作系统的方法汇编语言源程序返回操作系统的方法 :1.在代码段结束前加调用语句:MOV AH,4CH ;功能号4CHAHINT21H ;中断调用2.将主程序定义为远过程 CODE SEGMENT ASSUME CS:CODE主过程名 PROC FAR PUSH DS ;标准序MOV AX,0PUSH AX ;主程序 RET主过程名 ENDP CODE ENDS 汇编语言源程序语句格式汇编语言源程序语句格式汇编语言有两种语句:指令语句、指示语句,其格式是类似的:指令语句的格式

5、:标号: 操作符 参数,参数;注释指示语句的格式:名字 操作符 参数,参数,参数;注释 指令性语句指令性语句(真指令真指令)由CPU执行,每一条指令性语句都有一条机器码指令与其对应;指示性指示性(伪指令伪指令)语句由汇编程序语句由汇编程序执行。它控制汇编程序应如何对源程序进行汇编,如何定义变量、分配存储单元以及指示程序开始和结束等。指示性语句无机器码指令与其相对应。 注意: 指令性语句汇编时生成机器码;指令性语句汇编时生成机器码; 指示性语句汇编时不生成机器码。指示性语句汇编时不生成机器码。语句的构成元素:语句的构成元素:1.1.标号标号,名字名字(包括变量和常量包括变量和常量) 标号标号指令

6、的符号地址,用来代表指令在指令的符号地址,用来代表指令在存储器中的存储器中的地址地址。只能出现只能出现在指令性语句在指令性语句中,标号后应加上冒号。中,标号后应加上冒号。 变量变量段、过程、变量的名字,用来代表它们在段、过程、变量的名字,用来代表它们在存储存储器中的器中的地址地址。只能出现只能出现在指示性语句在指示性语句中,名字后不加冒中,名字后不加冒号。号。 常量常量代表一个表达式的结果。代表一个表达式的结果。只能出现只能出现在指示性语在指示性语句句中,名字后不加冒号。中,名字后不加冒号。它应符合下列规定:它应符合下列规定: 1)第一个字符必须是字母、问号)第一个字符必须是字母、问号“?”、

7、“”或或“-”; 2)从第二个字符开始可以是字母、数字、问号)从第二个字符开始可以是字母、数字、问号“?”、“”或或“-”; 3)最大长度为)最大长度为31个字符。个字符。 4)不应该是保留字。)不应该是保留字。 变量和标号都是符号地址,所以它们都有三个属性:段值变量和标号都是符号地址,所以它们都有三个属性:段值(SEGMENT)、段内的地址偏移量()、段内的地址偏移量(OFFSET)、类型)、类型(TYPE)。)。2.指令助记符指令助记符80868086的助记符、伪指令的助记符、伪指令3.操作数操作数即指令的操作对象即指令的操作对象对指令性语句对指令性语句( (真指令真指令)有有0 0,1

8、1或或2 2个个对指示性语句对指示性语句( (伪指令伪指令)根据需要而根据需要而定定操作数之间以逗号分隔操作数之间以逗号分隔操作数可以是:寄存器、存储单元(变操作数可以是:寄存器、存储单元(变量)、常数或表达式量)、常数或表达式 例如:例如:AXAX,DI+BX+10DI+BX+10,200200,1616* *8+TABLE8+TABLE,等等,等等有三种运算符:算术运算符、逻辑运算符和关系运算符;两种操作符:数值回送操作符和属性操作符。4.注释注释以分号开头,可放在指令后,也可 单独一行。 注意注解的写法。要写指令(段)在程序中的作用,而不要写指令的操作。 例如:以下为同一条指令写的注释

9、1)MOV CX,100 ;传送100到CX 2)MOV CX,100 ;循环计数器置初值 显然,第二种写法要比第一种写法要好。 汇编语言的一个实例: hello.asm Hello DB Hello, world!,0DH,0AH,$ ASSUME CS:prog,DS:datastart: MOV AX,data MOV DS,AX LEA DX,hello;取字符串首地址 MOV AH,9 INT 21H;显示字符串 MOV AH,4CH INT 21H;退回DOS名字标号伪指令 数据定义 伪指令 常数定义 伪指令 段定义和段寄存器指定伪指令 过程定义 伪指令 结束 伪指令数据定义及存储

10、分配伪指令:数据定义及存储分配伪指令: 用于定义变量,即内存单元或数据区。数据定义伪指令的格式为: 变量名变量名 DB/DW/DD/DQ/DT DB/DW/DD/DQ/DT 数据项表数据项表 ;注释;注释 常用的数据定义伪指令有如下几种: DB 定义字节字节 DW 定义字字 DD 定义双字双字操作数可以是常数、变量或表达式例例1 1:DATA_B DB 10,5,10HDATA_W DW 100H,-4DATA_D DD 0FFFBH汇编后的内存分配情况如右图所示。05H10H00H01HFCHFFHFBHFFH00H00H0AH例例2 2:操作数可以是字符串,例如STR DB HELLO 汇

11、编后的情况如图:STRHELLO注意注意: :下面两个定义的不同之处:DBAB ;41H在低字节,42H在高字节(先A后B)DW AB ;42H在低字节,41H在高字节(先B后A)48H45H4CH4CH4FH 操作数“?”用来保留存储空间,但不存入数据.例例3 3:ABC DB 0,1,2,3,4,OK,$ RSV DW ?,?,?,?,?,?,?,?复制操作符DUP: 重复的数据可以使用复制操作符DUP,格式为: DUP(表达式2)如上面RSV亦可写成: RSV DW 8 DUP(?)例例4 4: TABLE DB 10 DUP(?) BUFFER DW TABLE,$+3设TABLE的偏

12、移地址为0080H,则汇编后如下图所示:BUFFER0080H00HTABLE008AH008BH008CH008DH.8FH00H00H0089H10 Bytes若操作数中若使用$,则表示的是地址计数器的当前值。例: A1 DB 10,10H ;定义两个字节 A2 DW 10,10H ;定义两个字 A3 DB AB ;定义两个字节 A4 DW AB ;定义一个字 A5 DB 2 DUP(1,2,3)结果见例LI.ASM0A100A00100041424241010203010203常数定义伪指令 把一个表达式的值用一个符号表示,以后凡出现该表达式的地方都可用这个符号表示。 符号定义伪指令有两

13、种:EQU,=格式:符号名 EQU 表达式 符号名 = 表达式 用EQUEQU定义的符号未清除前,不能重新定义。清除EQU定义可用PURGEPURGE伪指令。 用”=”定义的符号可在任何时候进行重定义。 二者二者均不占用存储空间,仅是给符号赋值段定义伪指令段定义伪指令SEGMENT/ENDSSEGMENT/ENDS格式:段名 SEGMENT 定位类型 组合类型 类别 ;段内语句序列段名 ENDS 定位类型定位类型规定了对该段的起始地址的要求,可以有以下四种选择:PAGE(页):其16进制地址最低2位为00H。PARA(节):其16进制地址最低1位为0H。该类型为系统的缺省值。WORD(字):该

14、段从偶地址开始。BYTE(字节):组合类型组合类型表示该段与其它段之间的连接和定位关系,是在连接时起作用的。可以有以下六种选择:NONE:该类型为系统的缺省值。PUBLIC、STACK、COMMON、AT表达式、MEMORY。类别类别是由编程者赋予该段的与段名不同的另一个名字信息,必须用单引号括起来。在连接时由连接程序将程序中所有类别相同的段组成一个段组。段寻址伪指令段寻址伪指令ASSUMEASSUME该伪指令用来告诉汇编程序某个段是使用哪一个段寄存器。格式: ASSUME 段寄存器名:段名,段寄存器名:段名,过程定义伪指令过程定义伪指令定义子程序的格式为:过程名 PROC NEAR/FARR

15、ET过程名 ENDP程序结束伪指令程序结束伪指令ENDEND源程序结束伪指令表示一个程序模块的结束,其格式为:END 标号程序设计步骤程序设计步骤指令或语句指令或语句就是告诉计算机为完成某一计算步骤需要执行的操作。程序程序是为了求解某个问题所必须的完整的指令序列或语句串加上必要的数据。程序设计程序设计是编写程序的过程。当在设计一个程序时,应该考虑满足以下目标目标:1)程序的正确性。2)增强程序的可读性。3)所写程序应该是结构化的,易修改,易调试,即程序的可维护性。程序设计的基本步骤基本步骤1. 分析问题,建立模型例:Y=|X|Y= -X开始X=0Y= X结束Y= -X4分配存储空间和工作单元5

16、编写程序 6上机调试、运行程序2确定算法3根据算法画出程序流程图DOS系统功能调用系统功能调用(高级调用)(高级调用)作用:作用:调用由调用由操作系统操作系统OSOS提供的一组实现特殊功提供的一组实现特殊功能的子程序,以减轻编程工作量。能的子程序,以减轻编程工作量。它具有它具有90多个子功能多个子功能的子程序,它们通过的子程序,它们通过功能号功能号来区分。这些子程序组合在一起作为一个中断服来区分。这些子程序组合在一起作为一个中断服务程序,中断类型号为务程序,中断类型号为21H。实现实现方式:方式:用户程序在调用这些系统服务程序时,用户程序在调用这些系统服务程序时,不是不是用用CALL命令命令,

17、而,而是是采用软中断指令采用软中断指令INT n (INT 21H) 来实现来实现。 它不依赖于具体的硬件它不依赖于具体的硬件系统。系统。 内存管理、存取时间、存取终端矢量、终止程内存管理、存取时间、存取终端矢量、终止程序等。序等。注意注意:第二步和第四步并不是每个功能的调用都需要:第二步和第四步并不是每个功能的调用都需要的;若需要输入参数时,第一步和第二步顺序可换。的;若需要输入参数时,第一步和第二步顺序可换。这里只讨论几种常用的键盘输入键盘输入和显示输出显示输出的功能调用的功能调用。1. 1. 键盘输入功能调用键盘输入功能调用(1) 从键盘输入一个字符(功能号功能号=1=1) 格式格式:

18、MOV AH,MOV AH,1 1 INT 21H INT 21H功能:执行功能:执行1号系统功能调用时,系统等待键盘输号系统功能调用时,系统等待键盘输入,一旦有键按下,系统先检查是否是入,一旦有键按下,系统先检查是否是Ctrl-c键,键,如果是则退出程序,否则将键入的字符的如果是则退出程序,否则将键入的字符的ASCII码码值存入值存入AL中,并在屏幕上显示该字符。中,并在屏幕上显示该字符。例例: :程序中有时需要用户对提示做出应答。 GET_KEY: MOV AH,1;等待键入字符 INT 21H;结果在AL中 CMP AL,Y ;是Y? JZ YES ;是,转YES CMP AL,N ;是

19、N? JZ NO ;是,转NO JMP GET_KEY;否则继续等待输入 YES: NO: 7 7号功能调用号功能调用功能:执行功能:执行7号系统功能调用时,系统等待键盘号系统功能调用时,系统等待键盘输入,一旦有键按下,将键入的字符的输入,一旦有键按下,将键入的字符的ASCII码码值存入值存入AL寄存器中,不检查寄存器中,不检查Ctrl-c键,不回显。键,不回显。8 8号功能调用号功能调用功能与功能与1号功能调用类似,检查号功能调用类似,检查Ctrl-c键,不回显。键,不回显。(2) 输入字符串(功能号功能号= =0AH0AH) 此功能调用从键盘输入一串字符并把它存入用户指定的缓冲区中。 MO

20、V AH,MOV AH, 0AH 0AH LEA DX, LEA DX, INT 21H INT 21H (预留的预留的N1-1个字节的存储单元个字节的存储单元) 0DHN2N1 N1: 缓冲区长度缓冲区长度(最大键入字符数最大键入字符数) N2: 实际键入的字符数实际键入的字符数(不包括回车符不包括回车符) 用户定义的输入字符串的缓冲区分布用户定义的输入字符串的缓冲区分布 定义缓冲区的格式:定义缓冲区的格式:STR1 DB 10,?,10 DUP(?)调用前,要求DS:DX指向输入缓冲区的首地址;调用后,DS:DX仍指向输入缓冲区的首地址。2. DOS2. DOS显示功能调用显示功能调用(1

21、) (1) 在显示器上显示一个字符在显示器上显示一个字符( (功能号功能号= =2 2) ) MOV AH, MOV AH, 2 2 MOV DL, MOV DL, INT 21H INT 21H 例:在显示器上显示一个字符A MOV AH, 2 MOV DL, A ;或MOV DL, 41H INT 21H MOV AH, MOV AH, 9 9 LEA DX, LEA DX, INT 21H INT 21H注意:被显示的字符串必须以注意:被显示的字符串必须以$结束结束。(2)(2)显示字符串显示字符串(功能号功能号= =9 9)功能:将(DS:DX)指定内存缓冲区中的字符串(以“$”字符作

22、为结束符)在屏幕上显示出来。例:在屏幕上显示:HELLO,WORLD!;在数据段定义字符串: DATA SEGMENT STR1 DB HELLO,WORLD!$ DATA ENDS;在代码段中进行显示输出 MOV AH,9 LEA DX,STR1 INT 21H完整的程序: HELLO.ASM程序的基本结构程序程序是指令(语句)的有序集合,是对系统任务处理步骤的描述。程序的执行是有一定顺序的,依据执行顺序执行顺序可将程序分为如下基本结构:顺序结构、分支(选择)结构、循环结构和子程序结构顺序结构、分支(选择)结构、循环结构和子程序结构。顺序结构顺序结构:是一种线性结构,这种结构的程序每执行一次

23、,其中的语句或程序段依次被执行一次程序的顺序结构如图所示:S1S2S3其中S1、S2、S3表示顺序执行的语句或程序段。例例6-4 假设由下列数学公式:Y=X3+8X2+8X+6试编写当X=10时,计算Y值的程序。(X)AX(AX)+8AX (AX)*(X)AX(AX)+6AX(AX)+8AX (AX)*(X)AXAX (Y) Y=(X+8)X+8)X+6START: MOV AX,STACK_SEG MOV SS,AX MOV SP,OFFSET TOP PUSH DS SUB AX,AX PUSH AX MOV AX,DATA_SEG MOV DS,AX MOV AX,X ADD AX,8

24、MUL X ADD AX,8 MUL X ADD AX,6 MOV Y,AX RET MAIN ENDPCODE_SEG ENDS END STARTDATA_SEG SEGMENT X DW 10 Y DW 0 DATA_SEG ENDSSTACK_SEG SEGMENT STACK STACK DW 100 DUP (?) TOP LABEL WORDSTACK_SEG ENDSCODE_SEG SEGMENTMAIN PROC FAR ASSUME CS:CODE_SEG,DS:DATA_SEG ASSUME SS:STACK_SEGdata segment ;数据段 msg db 0d

25、h,0ah,07h,Hello$data endsss_seg segment ;堆栈段 db 256 dup(?)ss_seg endscode segment ;代码段 assume cs:code,ds:data,ss:ss_segmain proc far push ds ;标准序 mov ax,0 push ax mov ax,data ;设置数据段 mov ds,ax lea dx,msg ;取字符串地址执行后显示HELLO。mov ah,09h;显示字符串int 21h ret ;返回操作系统main endpcode endsend main标号:条件满足条件满足?处理处理分支

26、程序分支程序NYIFTHEN结构结构程序结构:程序结构: 测试测试/比较指令比较指令 (TEST/CMP) 条件转移指令条件转移指令 (Jx 标号标号) 处理体处理体 标号标号: 其他指令其他指令 程序结构:程序结构: TEST/CMP指令指令 Jx 标号标号1 处理体处理体P1 JMP 标号标号2标号标号1: 处理体处理体P2标号标号2:其他指令:其他指令 条件满足条件满足?处理处理P1处理处理P2标号1:标号2:IFTHENELSE结构结构YN例例: :编写程序计算Y=X,X,Y为字变量。DATA SEGMENT X DW 10H Y DW ?DATA ENDSCODE SEGMENTMA

27、IN PROC FAR ASSUME CS:CODE,DS:DATASTART:PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV AX,X TEST AX,8000H JZ POS NEG AXPOS: MOV Y,AX RETMAIN ENDPCODE ENDS END START开始X=0XY-XYNOYES结束CMP AX,0JGE POSAND AX,AXJNS POS标号标号1:条件条件1成立成立?P1NYCASE结构结构程序结构:程序结构: TEST/CMP指令(测试条件1) Jx 标号1 ;不满足转标号1 处理体处理体P1 J

28、MP 标号标号n+1标号1:TEST/CMP指令(测试条件2) Jx 标号2 ;不满足转标号2 处理体处理体P2 JMP 标号标号n+1标号2:TEST/CMP指令(测试条件3) Jx 标号3 ;不满足转标号3 处理体处理体P3 JMP 标号标号n+1标号3:TEST/CMP指令(测试条件4) 标号n+1:(公共出口)条件条件2成立成立?条件条件n成立成立?Pn+1标号标号2:标号标号n:标号标号n+1:P2PnNNYY例:编写程序,根据键盘输入的值,显示不同的内容。若输入数字“0”,则显示“You have input digit 0.”,若输入数字“1”,则显示“You have inpu

29、t digit 1.”若输入数字“9”,则显示“You have input digit 9.”,否则显示“Error!”。 DATASEGMENTDISDB0DH,0AH,Please input digit 09.$DIS0DB0DH,0AH,You have input digit 0.$DIS1DB0DH,0AH,You have input digit 1.$DIS9DB0DH,0AH,You have input digit 9.$DIS10DB0DH,0AH,Error!$DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART: MOVAX,D

30、ATA;初始化初始化DSMOVDS,AXLEADX,DISMOVAH,09H ;DOS功能调用:显示字符串功能调用:显示字符串INT21HMOVAH,01H ;从键盘输入一个字符从键盘输入一个字符,其其ASCII码送码送ALINT21HCMPAL,30H ;与与0的的ASCII码比较码比较JBERR;小于小于0的的ASCII码转码转EXITCMPAL,39H ;与与9的的ASCII码比较码比较JAERR;大于大于9的的ASCII码转码转EXITANDAL,0FH ;ASCII码码二进制二进制JMPGOODERR:MOVAL,10;如果输入的不是如果输入的不是09,AL寄存器送寄存器送10GOO

31、D: LEABX,TAB ;取地址表的偏移地址取地址表的偏移地址BXMOVAH,0SHLAL,1;JMP SHORT P*为两字节指令为两字节指令ADDBX,AXJMPBX;转到地址表中对应的指令去执行转到地址表中对应的指令去执行EXIT:MOVAH,4CH ;返回返回DOSINT21HTAB:JMPSHORT P0;地址表地址表JMPSHORT P1JMPSHORT P9JMPSHORT P10P0:LEADX,DIS0;将输出字符串存放的首址偏移量将输出字符串存放的首址偏移量DXMOVAH,9INT21HJMPEXIT;显示输出字符串显示输出字符串P10:LEADX,DIS10;将存放将存

32、放”ERROR$”字符地址偏移量字符地址偏移量;DX来显示来显示MOVAH,9INT21HJMPEXITCODEENDSEND START循环程序1DOUNTIL 结构 先执行,再判断条件先执行,再判断条件。工作部分至少执行一次。初始化初始化循环体循环体循环控制循环控制继续循环?继续循环?YN例例: :编写一程序,从数据段中一未排序的字数组ARRAY中,找出最大值和最小值分别存放到AX和BX 寄存器中。开始开始N-1N-1CXCX取数组第一个取数组第一个数数 AX AX和和BXBX数组中数与数组中数与(AX)AX)和和(BX)(BX)比较比较大数大数 AX AX小数小数 BX BX比较完比较完

33、?结束结束NYDATA SEGMENTN EQU 6ARRAY DW 98H,04H,76H,12H,09H,0F8HDATA ENDSCODE SEGMENTMAIN PROC FAR ASSUME CS:CODE,DS:DATASTART: PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV CX,N-1 LEA SI,ARRAY MOV AX,SI MOV BX,AXAGAIN: ADD SI,2 CMP BX,SI JLE FMAX MOV BX,SI JMP SHORT NEXTFMAX: CMP AX,SI JGE NEXT MO

34、V AX,SINEXT: LOOP AGAIN RETMAIN ENDPCODE ENDS END START2. DO WHILE 结构 先判断条件,再执行先判断条件,再执行。工作部分有可能一次都不执行。初始化初始化循环体循环体循环控制循环控制继续循环?继续循环?YN例:求平方根程序:内存SQU单元存放一个完全平方数,编一个求平方根程序。分析:从1开始连续I个奇数之和是I的平方数N,如:1+3+5+7+9+11+13=49,其中I=7(7个连续的奇数),N=49(连续奇数之和),所以N=I2;开始初始化平方值=0?平方数减奇数计数器加1形成下一个奇数保存结果结束DATA SEGMENTSQU

35、 DW 13924 ROOT DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA SQROOT: MOV AX,DATA MOV DS,AX XOR CX,CX ;计数器清0 MOV BX,1 ;置奇数 MOV DX,SQU ;把平方数送DXL1: AND DX,DX ;判断平方数是否为0 JZ L2 ;为0,退出 SUB DX,BX ;平方数减奇数 INC CX ;减奇数的次数加1 ADD BX,2 ;形成下一个奇数 JMP L1L2: MOV ROOT,CX ;保存结果 MOV AH,4CH ;返回DOS INT 21HCODE ENDS

36、END SQROOT 注意:注意:循环可以嵌套循环可以嵌套(多重循环多重循环),但多个循环体之间,但多个循环体之间不能交叉,控制条件不能混淆。不能交叉,控制条件不能混淆。例:例:采用采用“冒泡法冒泡法”把一个长度已知的数组元素按从小到把一个长度已知的数组元素按从小到大排序。假设数组中的元素为无符号字变量大排序。假设数组中的元素为无符号字变量 冒泡法冒泡法实例:实例:3,7,2,8,62, 3, 6, 7, 8 。内外两层循环;内外两层循环;每轮内循环使一个最大的数沉底,因为最大的数沉底,下轮每轮内循环使一个最大的数沉底,因为最大的数沉底,下轮内循环就不用再比较最底下的数,所以内循环的循环次数每

37、内循环就不用再比较最底下的数,所以内循环的循环次数每一轮比上一轮要逐次减一轮比上一轮要逐次减1;外循环用于控制有多少轮内循环。若有外循环用于控制有多少轮内循环。若有n个数据,则外循环次个数据,则外循环次数为数为n-1。见源程序见源程序DXUNHUAN.ASMDATASEGMENTADW8907,43,56,24,65,23,54,2,34,24NEQU ($-A)/2DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOV AX,DATA;初始化DSMOV DS,AXMOV CX,N-1;计数器MOV BX,0LOOP1:MOV DX,CX;保存外循环

38、计数MOV SI,0;设置内循环偏移地址LOOP2:MOV AX,ABX;取数,暂做小数CMP AX,ABX+SI+2;和其它数做比较JNAL1;小于等于,转L1MOV DI,ABX;否,则交换数据MOV AX,ABX+SI+2MOV ABX,AXMOV ABX+SI+2,DIL1:ADDSI,2;修改偏移指针,为下一次比较做准备LOOP LOOP2;内循环结束判断ADDBX,2;修改内循环的首址MOV CX,DXLOOP LOOP1;外循环结束判断MOV AH,4CH;返回DOSINT21HCODEENDSENDSTART掌握以下几点掌握以下几点: :调用子程序用CALLCALL指令,返回调

39、用程序用RETRET指令。子程序允许嵌套调用嵌套调用。进入子程序后首先要保护主程序的运行状态(标志位)和使用的寄存器内容(称为保护现场保护现场),退出子程序前要恢复现场恢复现场。调用前要预先确定子程序中要使用哪些寄存器使用哪些寄存器,并定义入口参数和出口参数定义入口参数和出口参数。参数传递可利用寄存器、存储单元或堆栈(要用BP寻址)。例例1: 二进制数二进制数(0-F)转换成转换成ASCII(0-F)的子程序。的子程序。BIN2ASC PROC ;要转换的数在AL的低四位 ;转换结果仍在AL中 CMP AL, 9 JA A2F ADD AL, 30H; 9, +37H DONE:RETBIN2

40、ASC ENDP调用方法:(在主程序中) MOV AL, 0CH CALL BIN2ASC (AL中有0CH的ASCII码43H, C)子程序的参数传递子程序的参数传递 编写子程序时,很重要的一个工作是如何把参数传给子程序,这个过程叫参数传送。 传送方法有:l把参数放在CPU内部寄存器中l把参数放在变量中l把参数放在地址表中l利用堆栈传送参数 下面举例介绍第4种方法,它通常在主程序中把参数或参数地址保存在堆栈中,而在子程序中将参数从堆栈取出来。例:把一个用十六进制表示的字ASCII码,然 后送到屏幕上显示。 汇编程序如下:DATASEGMENTNUMDW25AFH ;要显示的数STRINGDB

41、4 DUP(?),13,10,$DATAENDSSTACKSEGMENTDB 100 DUP(?)TOP EQU $ STACKENDS ; CODESEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVES,AXMOVAX,STACKMOVSS,AX MOV SP,offset TOP LEABX,STRING;取变量偏址PUSHBX;将偏址压栈PUSHNUM;将变量压栈00020064H0062HSP25AF0060H堆栈 CALLCALLBINHEXBINHEX;(SP)=005EH CS:011

42、3CS:0113 LEADX,STRING;(DX)=0002HMOVAH,9INT21HMOVAH,4CHINT21H;*BINHEXPROCPUSHBP;(SP)=005CHMOVBP,SP ;(BP)=005CHPUSHAX ;(SP)=005AHPUSHDI ;(SP)=0058HPUSHCX ;(SP)=0056HPUSHDX ;(SP)=0054H00020064H0062H25AF0060H005EH0113005CHSP返回地址(IP)原(BP)00020064H0062H25AF0060H005EH0113xxxx005CHBP PUSHF ;(SP)=0052H MOV A

43、X,BP+4 ;(AX)=25AFH MOV DI,BP+6 ;(DI)=0002H ADD DI,LENGTH STRING-1;(DI)=0005H MOV DX,AX ;(DX)=25AFH MOV CX,(STRING-num)*2 ;STD ;从后往前存AGAIN:AND AX,0FH ;第一次(AX)=000FH CALL HEXDCALL HEXD ;转换为ASCII码存于AL MOV DI,AL DEC DI; STOSB PUSH CX MOV CL,4 SHR DX,CL ;逻辑右移4位 MOV AX,DX ;第1次(AX)=025AH POP CX LOOP AGAIN

44、;(CX)-1=0?不等,转+4POPFPOPDX POPCXPOPDIPOPAXPOPBPRET4 BINHEX ENDP ;将AL中的一位16进制数转换为ASCIIHEXD PROC CMP AL,0AH JL LP ADD AL,7LP: ADD AL,30H RETHEXD ENDPCODE ENDS END BEGIN0064H0062H0060H005EH005CH000225AF0113xxxx(SP) 从本例可知,通过堆栈传递的两个参数分别为:变量NUM的内容25AFH和变量STRING的偏移地址。这两个参数在调用子程序之前压入堆栈,当CALL指令返回时,其(SP)=0060H

45、,不是初值0064H。故采用带参数返回指令RET 4。 本例重点掌握: 进一步了解堆栈的使用 学会RET n的应用 子程序嵌套1.码制转换 十、二进制数、ASCII码之间的互相转换。BCD数数2进制数进制数 算法:Dn-1*10n-1+D0*100 = (Dn-1*10+ Dn-2)*10+)*10+ D0 = (0*10+Dn-1)*10+ Dn-2)*10+)*10+ D0 即: 新的中间结果 = 中间结果*10+本位数字 (中间结果初值为0)常见程序设计举例程序1:将65535的非压缩BCD数转换成2进制数。 程序如下: ;数据段定义 mydata SEGMENT decnum DB 5

46、, 3, 0, 1, 9 ;BCD数 53019 binnum DW ?mydata ENDSprog SEGMENT ASSUME CS:prog,DS:mydataBegin: MOV AX, mydata MOV DS, AX MOV SI, OFFSET decnum MOV CX, 5 ;5位位BCD数数 MOV BX, 10 XOR AX, AX ;中间结果初始值为中间结果初始值为0Next: MUL BX ;中间结果中间结果*10+本位数字本位数字 ADD AL, SI ADC AH, 0 INC SI ;指向下位指向下位BCD数数 LOOP next MOV binnum, A

47、X ;保存结果保存结果 MOV AH, 4CH INT 21Hprog ENDS END begin程序程序2:把:把255的非压缩的非压缩BCD数转换成数转换成2进制数进制数 decnum DB 1,5,9 ;BCD数159 binnum DB ? MOV AX, word ptr decnum XCHG AH, AL ;百位在AH, 十位在AL AAD ;百位数*10 + 十位数 MOV AH, AL ;中间结果送AH MOV AL, decnum+2 AAD ;中间结果*10 + 个位数 MOV binnum, AL 例:从键盘输入两个整数例:从键盘输入两个整数, ,并求其和。并求其和。

48、 因键入为整数因键入为整数, ,故要进行如下转换:故要进行如下转换: ASCIIBCDASCIIBCD二进制数二进制数 ASCIIBCDASCIIBCD码很简单码很简单, ,高高4 4位清零即可得到非压位清零即可得到非压缩的缩的BCDBCD码。码。 BCDBCD二进制数在本例中采用用以下方法:二进制数在本例中采用用以下方法: ( ( (0+0+千位数千位数) )* *1010+ +百位数百位数) )* *10)+10)+十位数十位数) )* *10+10+个位数个位数 ASCIIASCII码码二进制数二进制数( (用于输入用于输入) ) 第一次中间结果第二次中间结果第三次中间结果最终结果开始开

49、始两个数分别转换成二进制数键入两个数键入两个数相加相加结束结束返回返回DOS如有溢出则提示如有溢出则提示开始取第一个ASCII码是负号吗?数字符个数1,指针1指针定位字符个数1= 0?取数字,与中间结果相加,再乘以10指向下一个数字字符加个位数是负数则求补存结果结束NYYN转换子程序转换子程序程序如下:DATASEGMENTSTR1 DB 7,?,7 DUP(?);第1个数的输入缓冲区STR2 DB 7,?,7 DUP(?);第2个数的输入缓冲区NUMDW ?,? ;存转换后的二进制数SUMDW 0 ;存和OVERDB Over flow!,0DH,0AH,$DATAENDS;CODESEGM

50、ENTASSUME CS:CODE,DS:DATAMAINPROC FARSTART: MOV AX,DATAMOV DS,AXMOV AH,0AHLEADX,STR1INT21H ;输入第一个数字串(设为26)MOV AH,0AHLEADX,STR2INT21H ;输入第二个数字串(设为33)LEABX,STR1 ;串1的首地址送BXLEADI,NUM ;存二进制首地址送DIMOV BP,10CALL CHANGE ;将串1 ASCII码二进制LEABX,STR2 ;串2的首地址送BX LEADI,NUM+2;指向MOV BP,10CALL CHANGE;将串2 ASCII码二进制 MOV

51、AX,NUM ;(AX)=NUM=001AHADD AX,NUM+2 ;两数相加,(AX)=003BHMOV SUM,AX;存和JNO NEXT;无溢出,转NEXTLEA DX,OVERMOV AH,9INT21H;显示Overflow!NEXT:MOV AH,4CHINT21H;返回DOSMAINENDPCHANGEPROCMOVCL,BX+1;实际字符数送CLMOVAL,BX+2;第一个字符送ALMOVCH,AL;暂存在CHCMPAL,-;第一个字符是负号吗?JNZNEXT1;不是,转NEXT1DECCL;字符数减1INCBXNEXT1: ADDBX,2;指向第一个数字字符MOVAX,0;

52、清零AX,存二进制数LP1: DECCLJZNEXT2;若(CL)=0,转NEXT2MOVDL,BX ;取字符ANDDL,0FH;转换成BCD码 ADD AL,DL ;加到中间结果上 ADC AH,0 MUL BP ;*10 INC BX ;指向下一个字符 JMP SHORT LP1NEXT2: MOV DL,BX ;取个位数 AND DL,0FH ;个位ASCII未组合BCDMOV DH,0 ADD AX,DX ;加个位数,(AX)=001AH CMP CH,- ;是-? JNZ NEXT3 ;该数非负,转NEXT3 NEG AX ;若为负,求补NEXT3: MOV DI,AX ;存二进制结果 RETCHANGE ENDP;CODE ENDS END START020732360D020733330D001A21003B00STR1STR2NUMSUM7个7个OOVER?0407313234STR1若键入 1234330D1234本例题重点掌握:如何从键盘输入一个字符串ASCII未组合BCD二进制有符号数的运算,对负数和溢出如何处理思考题: 若键入第一个数26,第二个数为-4,填写各变量结果。 方法1 计算二进制数中所包含的1000的个数、100的个数、10的个数和1的个数。 方法2 除10取余。下面举例介绍第一种方法。流程图如下:二进制数BCD YN

温馨提示

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

评论

0/150

提交评论