1、汇编语言程序设计1第四章 汇编语言程序设计(2)n汇编语言源程序的另一种结构n汇编语言中的操作数nDos 功能调用n汇编语言程序设计举例堆栈段数据段代码段 n一个基本的汇编语言程序框架如下:返回 stack SEGMENT PARA stack ;定义作为堆栈段的逻辑段,段名为stack DB 100 DUP(?);定义堆栈长度 top LABLE word ;定义栈底位置 stack ENDS data SEGMENT ;定义作为数据段的逻辑段,段名为data data ENDS code SEGMENT ;定义作为代码段的逻辑段,段名为;定义作为代码段的逻辑段,段名为code ASSUME
2、 CS:code,DS:data,ES:data,SS:stack start:MOV AX,data ;程序执行起始点程序执行起始点 MOV DS,AX MOV ES,AX;将各个段寄存器指向用户定义的各个逻辑段;将各个段寄存器指向用户定义的各个逻辑段 ;MOV AX,stack ;MOV SS,AX ;MOV SP,OFFSET TOP MOV AL,4CH ;系统功能调用,程序结束返回操作系统;系统功能调用,程序结束返回操作系统OS INT 21H code ENDS END start ;汇编结束,程序起始点为汇编结束,程序起始点为start汇编语言程序设计3关于源程序结构的几点说明n
3、在代码段中,assume语句只给出了各个段寄存器和各个自定义段的关系,并没有给各个段寄存器真正赋值。n段寄存器的赋值还要由程序本身来完成,如我们用到mov ax,data mov ds,ax mov es,ax 给ds和es赋值。第一条指令,将段基址送给目的操作数,这是mov 指令的一个特殊情况n为什么只给ds,es赋值,而不给cs,ss赋值?因为在dos环境下运行程序时,dos 的装入程序已经对cs:ip和ss:sp作了正确的初始化,而ds,es初始化为程序段前缀psp的起点,而非用户所需要的地址,所以我们要对它俩重新赋值 汇编语言程序设计4n在上面的结构中,程序结束后返回DOS操作系统用的
4、是:mov ah,4ch int 21Hn当用户程序结束时,返回dos操作系统还有一种常用的方法:1.首先把用户程序设置成一个过程,且类型设置为far。2.在用户程序程序开始处 push ds xor ax,ax push ax 在子程序结束时用ret指令。这样也可以返回dos操作系统。这实际上是用了int 20h中断指令。虽然我们从程序表面上没有看到这条指令,但是这条指令一定存在于用户程序的目标代码之前的程序段前缀区(program segment prefix)中。汇编语言程序设计5n原因是:每当一个用户程序的可执行文件(.exe)被DOS加载至内存中去时,它首先要为该程序建立一个一个文件
5、头,又叫程序段前缀(PSP),占100H(256)个字节,然后把可执行的程序代码加载至PSP的后续地址上。即CS指向地点。而DS和ES初始化在PSP的起始地址。内存分配如右图。PSP给出了用户可执行文件的若干控制信息,其中前两个字节是一条中断指令INT 20H,即程序结束返回DOS指令。当用户程序结束运行时,可以通过把程序执行地址返回PSP执行这条指令而终止自己的进程。这是一种传统方法系统占用程序段前缀PSP(共256个字节)用户数据段用户堆栈段用户代码系统和rom占用0HDS,ESsscs用户空间用户程序装入内存后的内存分配情况;在屏幕上输出字符串:hello,everyone!的另一种编程
6、Stack segmentDb 100 dup(?)Stack segmentdata segmentString db hello,everyone!,0dh,0ah,$Data segmentCode segmentProc1 proc far assume cs:code,ds:data,es:data,ss:stackStart:push ds sub ax,ax push ax mov ax,data mov ds,ax mov ah,09h mov dx,offset string;或lea dx,string int 21h retproc1 endpCode ends end
7、start汇编语言程序设计7DOS功能调用功能调用重点注意重点注意:1 1、DOS DOS功能调用的概念;功能调用的概念;2 2、DOS DOS功能调用中字符功能调用中字符I/OI/O功能的使用方法。功能的使用方法。汇编语言程序设计8一、一、DOSDOS功能调用的概念功能调用的概念 1、软件中断:、软件中断:格式:格式:INT nn为中断类型号,每个类型号对应一个四字节为中断类型号,每个类型号对应一个四字节的向量。的向量。8086有多达有多达256个不同的中断类型号向量,个不同的中断类型号向量,这些向量被存放在物理地址为这些向量被存放在物理地址为00000H003FFH的存的存储单元中。储单元
8、中。软件中断分为三类:软件中断分为三类:软件中断软件中断自由中断(自由中断(40HFFH)ROM BIOS中断(中断(10-1FH)DOS中断(中断(9个个 20H27H&2FH)2、DOS中断中断DOS中断中断(共(共9个)个)DOS可调用中断(可调用中断(6个,分别为:个,分别为:20H、21H、25H、26H、27H、2FH)DOS专用中断(专用中断(3个个 22H、23H、24H)3、DOS可调用中断可调用中断DOS可调可调用中断用中断假脱机打印文件中断(假脱机打印文件中断(2FH)程序退出中断(程序退出中断(20H、27H)磁盘读写中断(磁盘读写中断(25H、26H)DOS功能调用中
9、断(功能调用中断(21H)3、DOS功能调用中断(功能调用中断(INT 21H)(1)INT 21H 的中断向量的中断向量00000H00084H00087H003FFHINT 21H256个中个中断向量断向量(2)INT 21H 的子功能(共计的子功能(共计84个子功能)个子功能)按功能分按功能分为为11类类磁盘操作磁盘操作字符字符I/O程序结束程序结束文件操作文件操作网络共享网络共享AH02H,字符显示;,字符显示;DL=输出字符输出字符AH09H,字符串显示;,字符串显示;DS:DX=缓冲区首址缓冲区首址(3)INT 21H 的使用的使用 a、02H功能号的使用(显示字符功能号的使用(显
10、示字符B)MOV AH,02HMOV DL,BINT 21H b、09H功能号的使用(显示字符串功能号的使用(显示字符串1234567)数据段中:数据段中:BUFFERDB1234567,$代码段中:代码段中:MOV AX,SEG BUFFERMOV DS,AXMOV DX,OFFSET BUFFERMOV AH,09HINT 21HINT 20H例例1:在在CRT 上连续输出字符上连续输出字符09name output stack segment para stack stack db 100 dup(?)stack ends code segment assume cs:code,ss:s
11、tack start proc farbegin:push ds mov ax,0 push ax mov bl,0 push bxgoon:mov dl,20h mov ah,2 int 21h pop bx mov al,blinc aldaaand al,0fhmov bl,alpush bxor al,30hmov dl,almov ah,2int 21hmov cx,0fffhagain:dec cx jne again jmp goon retstart endpcode ends end begin二、二、I/O的的DOS 调用的例子调用的例子;返回返回DOS;延时延时例例2:在
12、:在CRT 上连续显示上连续显示0059name output_char_00_59stack segment para stack stackdb 100 dup(?)stack endsdata segmentbuffer db 3 dup(?)data endscode segment assume cs:code,ds:data,ss:stackStart proc farbegin:push dsmov ax,0push axmov ax,datamov ds,axmov ax,stackmov ss,axmov cx,1000mov bl,0lea si,bufferpush bx
13、;返回返回DOSgoon:mov dl,0dh mov ah,2 int 21h mov dl,0ah mov ah,2 int 21h pop bx mov al,bl inc al daa cmp al,60h jc next mov al,0next:mov bl,al push bx mov dl,al push cx mov cl,4 shr al,cl or al,30h mov si,al inc si mov al,dl and al,0fh or al,30h mov si,al inc si mov al,$mov si,al mov dx,offset buffer mo
14、v ah,9 int 21h mov cx,0ffffh;十位数数码转换成十位数数码转换成ASCII码后,保存码后,保存;个位数数码转换成个位数数码转换成ASCII码后,保存码后,保存;加结束标志加结束标志汇编语言程序设计15 again:dec cx jne again pop cx dec cx je done mov si,offset buffer jmp goondone:ret start endpcode endsend begin;延时延时汇编语言程序设计16小结:小结:1 1、DOSDOS功能调用功能调用INT 21HINT 21H,是,是DOSDOS系统内部的软件中断,系统
15、内部的软件中断,由近百个子程序组成,是由近百个子程序组成,是DOSDOS内核的主要组成部分。内核的主要组成部分。这些子程序被加载到连续的存储区中,其首地址这些子程序被加载到连续的存储区中,其首地址(即(即INT 21HINT 21H的中断向量)在中断向量表中的的中断向量)在中断向量表中的84H84H87H87H四个字节中,四个字节中,2 2个字节位段地址,个字节位段地址,2 2个字节位偏移量。个字节位偏移量。执行执行INT 21HINT 21H指令时,系统自动将指令时,系统自动将2 2个字节位段地个字节位段地址送址送CSCS,2 2个字节位偏移量送个字节位偏移量送IPIP,再根据,再根据AHA
16、H中的功能号,中的功能号,CPUCPU就可以跳到对应的子程序上执行,完成相应功能。就可以跳到对应的子程序上执行,完成相应功能。2、02H功能号和功能号和09H功能号是功能号是DOS功能调用功能调用INT 21H中的字符中的字符I/O功能,其使用方法如下:功能,其使用方法如下:a、02H功能号的使用(显示一个字符功能号的使用(显示一个字符)MOV AH,02HMOV DL,要显示的字符要显示的字符INT 21H b、09H功能号的使用(显示一个以功能号的使用(显示一个以$位结束符的字符串位结束符的字符串)MOV AX,字符串所在的段地址字符串所在的段地址MOV DS,AXMOV DX,字符串的偏
17、移量字符串的偏移量MOV AH,09HINT 21H汇编语言程序设计18汇编语言中的操作数n寄存器操作数,如ax,bx,bp,cx,dl等n常量n存储器操作数n常量包括常数常数、字符串常量,符号常量,字符串常量,符号常量,数值表达式数值表达式n常数二进制数,以B结尾。如01001101B。十进制数,如85。十六进制数,以H结尾。第1个数字为A-F时,前面应加0,如0F160H。字符串:用引号括起来的1个或多个字符。如ERROR!,a,汇编时被翻译成对应的ASCII码45H,52H,52H,4FH,52H,21H和61H。n字符串常量“AB”等价于4142h汇编语言程序设计20常量n符号常量 P
18、ORT_VAL EQU 3 就是把端口地址3定义为一个符号PORT_VALn数值表达式见后面一页表达式表达式是常数、寄存器、标号、变量与运算符的组合。有数字表达式和地址表达式两种。汇编时按优先规则对表达式进行计算,计算出具体的数值或地址。运行时不能改变。表达式中的运算符有6类:算术、逻辑、关系、取地址、属性、杂类。汇编语言程序设计22用于数字表达式,例:MOV AX,4*1024汇编后的形式为:MOV AX,4096 用于地址表达式,例:LEA SI,TAB+3若TAB的偏移地址为1000H,则汇编后的形式为:LEA SI,1003H 1)算术运算符+、-、*、/,MOD汇编语言程序设计23逻
19、辑运算符只能用于数字表达式中。例:MOV CL,36H AND 0FH 经汇编后:MOV CL,06H注意,不要把逻辑运算符与逻辑运算指令混淆:例:AND AX,3FC0H AND 0FF00H 汇编后源操作数被翻译为:3F00H,所以上述指令与AND AX,3F00H等价。2)逻辑运算符 AND、OR、XOR、NOT汇编语言程序设计24关系运算的结果是一个逻辑值:真真或假假 关系为真,结果为全1 关系为假,结果为全0例:MOV BX,PORT GT 300H 若PORT的值大于300H,则汇编后为:MOV BX,0FFFFH 否则汇编后为:MOV BX,03)关系运算符EQ、NE、LT、GT
20、、LE、GE汇编语言程序设计25SEG:取变量/标号的段地址OFFSET:取变量/标号的偏移地址例:VAR DB 12H MOV BX,OFFSETVAR;取变量VAR的偏移地址 MOV AX,SEG VAR ;取变量VAR的段地址注意,以下指令的异同:MOV BX,OFFSET VAR LEA BX,VAROFFSET只能取静态的偏移地址;LEA指令即可取静态的偏移地址,也可取动态的偏移地址。4)取地址运算符SEG、OFFSET汇编语言程序设计26nTYPE 取变量的类型(取变量的类型(1,2,4)nLENGTH 取所定义变量的长度取所定义变量的长度 (即变量中元素的个数)(即变量中元素的个
21、数)nSIZE 取所定义存储区的字节数取所定义存储区的字节数 (=TYPE*LENGTH)例:例:VAR DW 1,2,3,4,5 则 TYPE VAR=2 LENGTH VAR=5 SIZE VAR =105)取值运算符TYPE、LENGTH、SIZE汇编语言程序设计276)属性运算符PTR新属性 PTR 表达式例如:F1 DW 1234H F2 DB 23H,56H,18H MOV AL,BYTE PTR F1;AL=34H MOV BX,WORD PTR F2;BX=5623H与LABEL伪操作指令功能类似。LABEL可以对已定义的内存单元的属性重定义,并取一个新名字。汇编语言程序设计2
22、8复习LABEL伪指令功能例子:CFB LABEL BYTE;DFW DW 4567H EFW LABEL WORD FFB DB 89H,40H MOV AL,CFB;al=67h MOV BX,EFW;bx=4089h MOV CX,DFW;cx=4567h MOV AH,FFB;ah=89h可以看出,LABEL可以使一个变量具有多种属性,(当然也有多个名字)。LABEL语句本身不分配内存单元。汇编语言程序设计29存储器操作数:标号存储器操作数:标号、变量变量存储器操作数通常是标志符,可以分成标号(label)和变量(variable)两种。标号是可执行的指令语句的符号地址,通常是作为转移
23、指令jmp和调用指令call的目的操作数。变量名是一个数据项的第一个字节相对应的标识符。标号和变量有三个属性:段地址、偏移量、类段地址、偏移量、类 型型变量的类型:byte,word,dword标号的类型:near,far汇编语言程序的设计及举例概述汇编语言程序的设计及举例概述(一)编写汇编语言程序的步骤(一)编写汇编语言程序的步骤1、明确任务,确定算法;、明确任务,确定算法;2、绘流程图、绘流程图3、根据流程图编写程序、根据流程图编写程序4、上机调试、上机调试(二)判断程序质量的标准(二)判断程序质量的标准1、程序的执行时间、程序的执行时间2、程序所占用的内存字节数、程序所占用的内存字节数3
24、、程序语句行数、程序语句行数(三)标准流程图符号(三)标准流程图符号起始和终止框起始和终止框执行框执行框判断框判断框连接框连接框汇编语言程序设计32三种基本结构程序设计三种基本结构程序设计重点注意:重点注意:1 1、3 3种基本结构程序的特点种基本结构程序的特点2 2、3 3种基本结构程序流程图的画法种基本结构程序流程图的画法汇编语言程序设计33一、直线运行程序设计(顺序程序设计)一、直线运行程序设计(顺序程序设计)例例4.1 两个两个32位无符号数的乘法位无符号数的乘法 直线运行程序是按照语句实现的先后次序执行一系直线运行程序是按照语句实现的先后次序执行一系列的操作,它没有分支、循环和转移列
25、的操作,它没有分支、循环和转移 分析:可利用分析:可利用1616位乘法指令做位乘法指令做4 4次乘法,然后把部分积相次乘法,然后把部分积相加来实现加来实现 A B C D H H BD A D B C A C 6464位乘积位乘积 部分积部分积1+部分积部分积2部分积部分积3部分积部分积4最后乘积最后乘积汇编语言程序设计34例如:例如:1234 5678 8765 4321 H H 16AC 8D7804C4 F4B42DBB 655809A0 9A8409A0 CD05 70B8 8D785678*4321+1234*43215678*87651234*8765 H汇编语言程序设计35程序的
26、流程图程序的流程图源程序为:源程序为:data segment mulnum dw 0000,0ffffh,0000,0ffffh,4dUP(?)data endsname 32bit mutiply stack segment para stack stack db 100 dup(?)stack ends code segment assume cs:code,ds:data,ss:stack,es:data code段段安排各段的段寄存器安排各段的段寄存器定义定义stack段段0000FFFF0000FFFF0000000200040006 0008000A000C000emulnumD
27、ATA 段的内存情况段的内存情况B(0000单元单元)A(0002单元单元)D(0004单元单元)C(0006单元单元)begin:push ds mov ax,0 push ax start proc far mulu32:mov ax,bx mov si,bx+4 mov di,bx+6 mov ax,data mov ds,ax mov es,ax设置返回设置返回DOSDOS的段地的段地址和址和IPIP,与最后的,与最后的RET RET 一起使程序完成一起使程序完成后返回后返回DOS DOS 给各段寄存器赋值给各段寄存器赋值 lea bx,mulnum mul si mov bx+8,a
28、x mov bx+0a,dx mov ax,bx+2 mul si add ax,bx+0ahadc dx,0 mov bx+0ah,ax mov bx+0ch,dx mov ax,bx mul di add ax,bx+0ah adc dx,bx+0ch mov bx+0ah,ax mov bx+0ch,dx pushf mov ax,bx+2 mul di popf mov bx+0ch,ax mov bx+0eh,dx adc ax,bx+0ch adc dx,0 ret start endp code ends end begin结束语句结束语句 4.5.2 4.5.2 分支程序设计分
29、支程序设计 (1)分支结构根据不同情况做出判断)分支结构根据不同情况做出判断和选择,以便执行不同的程序段。分支的和选择,以便执行不同的程序段。分支的意思是在两个或多个不同的操作中选择其意思是在两个或多个不同的操作中选择其中的一个。中的一个。(2)分支结构在设计时经常用到跳转指)分支结构在设计时经常用到跳转指令如:令如:JMP、JE/JZ JNE/JNZ 、JS、JNS、JP、JNP、JO、JNO、JA、JNA、JG、JGE、JL、JNL、JNG汇编语言程序设计41【例】【例】编写计算下面符号函数的程序:编写计算下面符号函数的程序:1X0Y=0X=0 -1X设输入数据为设输入数据为buffer、
30、输出数据放入、输出数据放入BX分析:想让分析:想让X的值的特征反映在标志位上,可以采用的值的特征反映在标志位上,可以采用自身相自身相“或或”或者相或者相“与与”,结果不变,但影响了标,结果不变,但影响了标志位。还可以用志位。还可以用 与与0相比较的方法相比较的方法xy=-1X0X=0y=0y=1入口入口出口出口程序的流程图程序的流程图部分程序段如下:部分程序段如下:SIGEF:MOV AX,BUFFER OR AX,AX JE ZERO JNS PLUS MOV BX,0FFH;自身相或,影响标志位;自身相或,影响标志位;等于;等于0 0转移到转移到ZEROZERO;为正值转移到;为正值转移到
31、PLUSPLUS;为负值,把;为负值,把-1-1给给BXBX JMP COUT1ZERO:MOV BX,0 JMP COUT1PLUS:MOV BX,1COUT1:;跳转到其他处理程序;跳转到其他处理程序汇编语言程序设计43循环程序结构的组成:循环程序结构的组成:(1)循环体)循环体(2)循环结束条件)循环结束条件循环工作部分循环工作部分循环控制部分循环控制部分(3)循环初态)循环初态循环工作部分初态循环工作部分初态结束条件初态结束条件初态4.5.3 循环程序设计循环程序设计汇编语言程序设计441、用计数器控制循环、用计数器控制循环【例【例4.1】在一给定个数的数串中寻找最大值(或者】在一给定
32、个数的数串中寻找最大值(或者最小值),并且放在指定的单元。每个数用最小值),并且放在指定的单元。每个数用16位表位表示。示。分析:可以取出第一个数据来,然后和下一个数相分析:可以取出第一个数据来,然后和下一个数相比较。如果第一个数据大于下一个数,就继续找再比较。如果第一个数据大于下一个数,就继续找再下一个进行比较,若是第一数小于下一个数,就把下一个进行比较,若是第一数小于下一个数,就把第一个数用下一个数替换掉,以它作为大数继续和第一个数用下一个数替换掉,以它作为大数继续和下面的数据进行比较。如此循环直到找到最大的数下面的数据进行比较。如此循环直到找到最大的数我们可以设置我们可以设置AX寄存器作
33、为放最大数寄存器。寄存器作为放最大数寄存器。源程序:源程序:DATA SEGMENT BUFFER DW X1,X2,.X nCOUNT EQU$-BUFFERMAX DW?DATA ENDS;BUFFER单元置串单元置串;串的长度;串的长度;存放最大值;存放最大值NAME SEARCH_MAXSTACK SEGMENT STACK STACK DB 64 DUP(?)(?)TOP EQU$-STACKSTACK ENDS定义堆栈段定义堆栈段TOP为堆栈为堆栈指针指针SPCODE SEGMENT START PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACKBEG
34、IN:PUSH DS MOV AX,0 PUSH AXSTART:MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AXMOV CX,COUNTLEA BX,BUFFERINC BXDEC CXMOV AX,BXAGAIN:CMP AX,BX JGE NEXT MOV AX,BX NEXT:INC BX LOOP AGAIN START ENDPCODE ENDS END START RET ;如果下一个数大于这个数转到如果下一个数大于这个数转到NEXT;否则否则 把下一个数给把下一个数给AX;设置地址指针设置地址指针
35、;把第一个数据给把第一个数据给AX;设置地址指针增量设置地址指针增量;循环未完成继续循环未完成继续;设置计数器;设置计数器;计数减量;计数减量2.多重循环多重循环 在一个循环中包含另一个循环,称为多重循环,也叫在一个循环中包含另一个循环,称为多重循环,也叫循环的嵌套循环的嵌套例:一个利用多重循环设计延时的子程序例子例:一个利用多重循环设计延时的子程序例子DELAY:MOV DX,3FFHTIME:MOV AX,0FFFFHTIME1:DEC AXNOPJNE TIME1DEC DXJNE TIMERET汇编语言程序设计49小结:小结:1、顺序结构也称为线性结构,其中的与具备、顺序结构也称为线性
36、结构,其中的与具备连续执行。连续执行。2、分支结构也称为条件结构,程序结构有两、分支结构也称为条件结构,程序结构有两个以上的分支,程序的分支要靠条件转移指个以上的分支,程序的分支要靠条件转移指令来实现。令来实现。3、循环结构包括循环初态、循环体和循环结、循环结构包括循环初态、循环体和循环结束条件,根据循环体和循环条件的先后关系束条件,根据循环体和循环条件的先后关系循环结构可以分为当型循环循环结构可以分为当型循环while-do和直到型和直到型循环循环do-until。汇编语言程序设计50字符串处理程序设计和码转换程序设计字符串处理程序设计和码转换程序设计重点注意:重点注意:1 1、字符串在计算
37、机中的表现形式和处理技巧;、字符串在计算机中的表现形式和处理技巧;2 2、子程序的使用。、子程序的使用。汇编语言程序设计51一、一、字符串处理程序的设计字符串处理程序的设计 字符串是一系列连续的字符串是一系列连续的ASCII码或汉字内码的码或汉字内码的组合,汇编语言中一般只使用组合,汇编语言中一般只使用ASCII码。码。ASCII码共计码共计128个,分为显示字符和控制字个,分为显示字符和控制字符两类。符两类。(1)计算机不区分可打印字符和不可打印字符,而)计算机不区分可打印字符和不可打印字符,而I/O装置区分,不同的设备对装置区分,不同的设备对ASCII码的解释往往不同,一码的解释往往不同,
38、一般般I/O装置只按装置只按ASCII码处理数据。码处理数据。(2)一些广泛使用的控制字符:)一些广泛使用的控制字符:0DH回车(回车(CR),),20H 空格(空格(SP),),0AH 换行(换行(LF)(3)基本的)基本的ASCII码字符集是码字符集是7位的,在微机中用一个位的,在微机中用一个字节表示。高位为字节表示。高位为0。有时高位也用作校验。有时高位也用作校验。【例【例4-3】设字符串的结束标志为设字符串的结束标志为0DH(回车),统(回车),统计字串中字符的个数。计字串中字符的个数。置串指针置串指针置串长度的初值置串长度的初值取单元元素取单元元素=?CRCR串长度加串长度加1 1存
39、串长度存串长度返回返回Y YN N流程图如下:流程图如下:name length_of _string data segment string db abcduvwxyz,0dh ll db?cr equ 0dh data ends stack segment para stack stack db 100dup(?)stack ends code segment assume cs:code,ds:data,es:data,ss:stack start proc far begin:push ds mov ax,0 push ax mov ax,data mov ds,ax mov es,a
40、x lea di,string mov dl,0 mov al,cr again:scasb je done inc dl jmp again done:lea bx,ll mov bx,dlret start endp code ends end begin;设置串地址指针;设置串地址指针;置串长度的初值;置串长度的初值 ;alal中放的是回车符中放的是回车符 ;搜索回车符;搜索回车符 ;搜索到跳转到;搜索到跳转到donedone单元单元 ;没搜索到;没搜索到dldl内容内容 加加1 1 ;继续搜索;继续搜索结束结束;把串长度保存;把串长度保存 在在llll中中 为避免出现死循环,可以用循环
41、次数控制循环,要求为避免出现死循环,可以用循环次数控制循环,要求循环次数大于字符串的长度,若查找完整个字符串都没有循环次数大于字符串的长度,若查找完整个字符串都没有找到结束字符,转到出错处理。找到结束字符,转到出错处理。置串指针置串指针置串长度的初值置串长度的初值取单元元素取单元元素=?CRCR串长度加串长度加1 1存串长度存串长度返回返回Y YN NCXCX-1ZF=?0出错处理出错处理 data segment string db abcduvwxyz,0dh count equ$-string ll db?data ends stack segment para stack stack
42、db 100dup(?)stack ends code segment Assume cs:code,ds:data,es:data,ss:stack start proc far begin:push ds mov ax,0 push ax mov ax,data mov ds,ax mov es,ax lea di,string mov dl,0 mov al,0dh mov cx,count+10 again:scasb je done inc dl dec cx jne again jmp errordone:mov ll,dlerror:retstart endpcode ends
43、end begin;置循环次数大于串的长度置循环次数大于串的长度;规定的次数未完继续规定的次数未完继续;由计数停止循环,则转出错处理程序由计数停止循环,则转出错处理程序【例【例4-44-4】有一个起始地址为】有一个起始地址为STRING ASCIISTRING ASCII字符串,要求从串中字符串,要求从串中取出每个字符,根据其中包含的取出每个字符,根据其中包含的“1”1”的个数为奇数还是偶数,的个数为奇数还是偶数,在字节的最高位添入在字节的最高位添入“0”0”或者或者“1”1”,设该校验为偶校验,设该校验为偶校验 。流程图如右图:流程图如右图:返回返回初始化:串的地址指针,串的长度初始化:串的
44、地址指针,串的长度取入串元素取入串元素自行自行“与与”运算运算最高位置最高位置“1”1”“1”“1”的个数为的个数为偶数?偶数?送回串中送回串中串长度减串长度减1 1后后=0=0?N NY YN NY Yname parity_check stack segment para stack stackdb 100 dup(?)stack ends code segment assume cs:code,ds:data,ss:stack,es:data start proc far begin:push ds mov ax,0 push ax data segment string db 1234
45、567890 count equ$-string data ends mov ax,data mov ds,ax mov es,ax lea di,string mov cx,count again:lodsb and al,al jpe next or al,80h mov si-1 ,al next:dec cx jnz again retstart endpcode ends end begin DATA SEGMENTL1 DW 2STRING DB 34H,98HL2 DW?BUFFER DB 2*2 DUP(?)(?)DATA ENDSSTACK SEGMENTDB 100 DUP
46、(?)STACK ENDSCODE SEGMENT.START PROC FARBEGIN:.MOV CX,L1LEA BX,STRINGLEA SI,BUFFERMOV AX,CXSAL CX,1MOV L2,CXMOV CX,AX二、码转换子程序的设计二、码转换子程序的设计例例4-5:4-5:将一个字节的二进制数用十六进制数的将一个字节的二进制数用十六进制数的ASCIIASCII码表示码表示AGAIN:MOV AL,BX MOV DL,AL AND AL,0FH CALL CHANGE MOV AL,DL PUSH CX MOV CL,4 SHR AL,CL POP CX CALL CHA
47、NGE INC BX LOOP AGAIN RET START ENDPCHANGE PROC CMP AL,10 JL ADD_0 ADD AL,A-0-10ADD_0:ADD AL,0 MOV SI,AL INC SI RET CHANGE EDNPCODE ENDS END BEGIN取二进制数字节的低取二进制数字节的低4 4位进行转换位进行转换取二进制数字节的取二进制数字节的高高4 4位进行转换位进行转换.LEA DI,STRINGMOV CX,LENGTH STRINGPUSH DIPUSH CXMOV AL,30HREP STOSBPOP CXPOP DIMOV AL,31HMOV
48、 BX,NUMAGAIN:RCL BX,1 JNC NEXT MOV DI,ALNEXT:INC DI LOOP AGAIN RET.例例4-6:4-6:将一个二进制位串用其对应的将一个二进制位串用其对应的ASCIIASCII码表示码表示小结:小结:1 1、字符串在程序中的表示形式有两种:、字符串在程序中的表示形式有两种:ASCIIASCII码值的形码值的形式和单引号括起来的字符串的形式。如式和单引号括起来的字符串的形式。如DB 31H,32H,33H,34HDB 31H,32H,33H,34HDB 1234DB 1234这两句的作用是一样的。这两句的作用是一样的。2 2、设计子程序时,若在同一个段内,则定义为、设计子程序时,若在同一个段内,则定义为NEARNEAR型,型,不在同一段内,必须定义为不在同一段内,必须定义为FARFAR型。调用子程序时注意型。调用子程序时注意两个问题:两个问题:调用之前的寄存器保护为题;调用之前的寄存器保护为题;主程序和子程序参数传递的问题。主程序和子程序参数传递的问题。