1、微机原理与接口技术,第四章 汇编语言程序设计,主要内容,汇编语言的特点和编译过程汇编语言源程序格式指示性语句系统功能调用方法汇编程序设计方法综合举例,汇编语言的特点和编译过程,汇编语言对机器的依赖性很大,每种机器都有他专用的汇编语言,低级语言,编程困难。汇编指令是符号化的机器指令,和机器指令一一对应汇编指令的目标代码占用的内存少,执行速度快,效率高,实时性强。可以直接操作计算机硬件,例如寄存器。用汇编语言编写的程序为“源程序”,扩展名为“.asm”,可以用各种文本编辑软件编写。源文件经过“编译”,翻译成计算机可以识别和运行的二进制代码(目标程序,也称为OBJ文件)。完成汇编任务的程序称为“汇编
2、程序”。常用的汇编程序为MASM.EXE。目标程序还不能直接被计算机运行,需要经过“连接程序”,形成可执行程序(.EXE),才能被计算机运行。,汇编语言源程序格式,完整的汇编语言源程序由逻辑段组成。一个汇编语言源程序可以包含若干个代码段、数据段、附加段或堆栈段。段与段之间的顺序可随意排列。需独立运行的程序必须包含一个代码段,并指示程序执行的起始点,一个程序只有一个起始点。通常,程序还需要一个堆栈段。段由若干语句组成,一条语句通常写成一行。,一个完整的汇编语言源程序,DATA SEGMENTMINUS DB ?NUMBER DB 100DUP(?)DATA ENDSCODE SEGMENTASS
3、UME CS:CODE, DS:DATACOUNT EQU 100START:MOV AX, DATAMOV DS, AXMOV MINUS, 0LEA SI, NUMBERMOV CX,COUNTAGAIN:MOV AL, SIOR AL, ALJNS NOT_MINUS,INC MINUSNOT_MINUS:LOOP AGAINMOV AH, 4CHINT 21HCODE ENDSEND START,汇编语言的语句格式,指令性语句指令性语句用于表达处理器指令(我们上一章学习的各条指令),汇编后对应一条指令代码(目标代码),对应着CPU的一种操作。因而是可执行语句标号: 操作数 ;注释指示性
4、语句指示性语句指示源程序如何汇编、段和变量怎样定义、过程怎么设置,也称为伪指令(指示性、引导性),在汇编时运行,在汇编阶段已经全部完成,在目标程序中,是不存在伪指令的。是不可执行语句名字 参数 ;注释,每个部分称为“项”或“域”、“场”。标号后有:,加的部分不可缺少。,指令与伪指令,指令(Instruction)让CPU产生动作,在程序执行时才处理。指令就是第3章学习的处理器指令,与具体的处理器有关、与汇编程序无关。伪指令(Directive)不产生CPU动作,在程序执行前由汇编程序处理。伪指令与具体的处理器类型无关,但与汇编程序有关。不同版本的汇编程序支持不同的伪指令。,指令和伪指令采用易于
5、记忆的符合表达,这就是助记符,标号、名字与标识符,标号是反映指令位置(逻辑地址)和属性的标识符,后跟一个冒号分隔名字是反映伪指令位置(逻辑地址)和属性的标识符,后跟空格或制表符分隔,没有冒号标识符(Identifier)一般最多由31个字母、数字及规定的特殊符号(如 _、$、?、)组成,不能以数字开头。默认情况下,汇编程序不区别标识符中的字母大小写一个源程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字和内部寄存器名。,保留字,保留字(Reserved Word)是汇编程序已经利用的标识符(也称为关键字),主要有:指令助记符例如:MOV、ADD伪指令助记符例如:DB、DW操作符例如
6、:OFFSET、PTR寄存器名例如:AX、CS,汇编语言大小写不敏感,操作数和参数,处理器指令的操作数可以是立即数、寄存器和存储单元伪指令的参数可以是常量、变量、表达式等,可以有多个,参数之间用逗号分隔,注释,语句中由分号“;”开始的部分为注释内容,用以增加源程序的可读性必要时,一个语句行也可以由分号开始作为阶段性注释汇编程序在翻译源程序时将跳过该部分,不对它们做任何处理,分隔符,语句的4个组成部分要用分隔符分开标号后用冒号:,注释前用分号;操作数之间和参数之间使用逗号分隔其他部分通常采用空格或制表符多个空格和制表符的作用与一个相同,常量、变量和标号,汇编语言的数据可以简单分为常量和变量常量可
7、以作为指令的立即数或伪指令的参数,变量主要作为存储器操作数汇编语言语句中的名字和标号具有逻辑地址和类型属性,主要用做地址操作数,也可以作为立即数和存储器操作数,常量,常量表示一个固定的数值,它又分成多种形式,可以以多种数制及字符形式出现。数字常量 (2、8、10、16进制数)字符串符号常量数值表达式,(1) 数字常量,指由10、16、2和8进制形式表达的数值,各种进制的数据以后缀字母区分,默认不加后缀字母的是十进制数,(2) 字符串,字符串常量是用单引号括起来的单个字符或多个字符其数值是每个字符对应的ASCII码值例如:d(等于64H)AB(等于4142H)Hello, Assembly !,
8、(3) 符号常量,符号常量使用标识符表达一个数值用来为常量定义符号名符号定义伪指令有“等价EQU”和“等号”:符号名 EQU 数值表达式符号名 数值表达式EQU不能重复定义符号名,但“”允许重复定义。例如:X = 7;等效于:X equ 7X = X+5;“X EQU X+5”是错误的,举例,NUMBER EQU200COUNT EQU6*9ADDR EQUES:DI+2 MV EQUMOVSTRW EQUWORD PTR STRINGCOUNT = 123COUNT = COUNT +1,(4) 表达式,表达式一般是由运算符连接的各种常量所构成汇编程序在汇编过程中计算表达式,最终得到一个确定
9、的数值,所以也是常量表达式的数值在程序运行前的汇编阶段计算,所以组成表达式的各部分必须在汇编时就能确定经常使用的是加减乘除( * / )例如:mov ax,3*4+5;等价于:mov ax,17and ax, 3 and 5 ;等价于:and ax, 1,变量,变量实质上是指内存单元的数据,是对内存单元所起的名字,变量名实际上是内存单元的符号地址。虽然内存单元地址不变,但其中存放的数据可以改变变量需要事先定义才能使用变量定义(Define)伪指令为变量申请若干个固定长度(字节、字、双字等)的存储空间,并可以同时将相应的存储单元初始化定义后的变量可以利用变量名等方法引用其中的数据,即变量的数值,
10、(1) 变量的定义,变量定义的汇编语言格式为:变量名 伪指令 初值表变量名为用户自定义标识符,表示初值表首元素的逻辑地址,常称为符号地址。变量名也可以没有初值表是用逗号分隔的参数,主要由常量、数值表达式或“?”组成。其中“?”表示未赋初值多个存储单元如果初值相同,可以用复制操作符DUP进行定义:重复次数 DUP(重复参数)变量定义伪指令有DB、DW、DD等,字节变量的定义DB,DB伪指令用于分配一个或多个字节单元,并可以将它们用初值表初始化为指定值初值表中每个数据一定是字节量,存放一个8位数据:可以是0255的无符号数或是128127带符号数也可以是字符串常数,字节变量定义实例,;数据段Xdb
11、 a,-5db 2 dup(100),?Ydb ABC,应用,字节变量的应用,mov al,X ;此处X表示它的第1个数据,故ALadec X+1 ;对X为始的第2个数据减1,故成为6mov Y,al ;现在Y这个字符串成为 aBC,字变量的定义DW,DW伪指令用于分配一个或多个字单元,并可以将它们用初值表初始化为指定值初值表中每个数据是字量,一个字单元可用于存放任何16位数据:一个段地址一个偏移地址两个字符065535之间的无符号数3276832767之间的带符号数,字变量定义实例,;数据段countdw 8000h,?,ABmaxintequ 64hnumberdw maxintarray
12、dw maxint dup(0),P116 例题4.7,ADDR1 DB ABADDR2 DW AB,低地址,高地址,ADDR2,ADDR1,双字变量的定义DD,DD伪指令用于分配一个或多个双字单元,并可以将它们用初值表初始化为指定值初值表中每个数据是一个32位的双字量:可以是有符号或无符号的32位整数也可以用来表达16位段地址(高位字)和16位的偏移地址(低位字)的远指针 varddDD 0,?,12345678h farpoint DD 00400078h如果DD后操作数是变量名,表示把变量名的段地址和偏移地址存入对应的双字单元,(2)变量的应用,变量具有存储单元的逻辑地址程序代码中通过变
13、量名引用其指向的首个数据通过变量名加减位移量存取以首个数据为基地址的前后数据,变量的定义,bvar1db 100,01100100b,64h,d ;字节变量:不同进制表达同一个数值,内存中有4个64Hminint= 5 ;符号常量:minint数值为5,不占内存空间bvar2db -1,minint,minint+5 ;内存中数值依次为FFH,5,0AHdb ?,2 dup(20h) ;预留一个字节空间,重复定义了2个数值20Hwvar1dw 2010h,4*4 ;字变量:两个数据是2010H、0010H,共占4个字节wvar2dw ? ;wvar2是没有初值的字变量,变量的定义(续),dva
14、rdd 12347777h,87651111h,? ;双字变量:2个双字数据,一个双字空间abcdb a,b,c,?;定义字符,实际是字节变量maxint equ 0ah;符号常量:maxint10stringdb ABCDEFGHIJ ;定义字符串:使用字节定义DB伪指令crlfsdb 13,10,$ ;回车符0DH、换行符0AH和字符$24Harray1dw maxint dup(0) ;10个初值为0的字量,可以认为是数组arraydb 2 dup(2,3,2 dup(4) ;6个字节内容依次为:02 03 04 04 02 03 04 04,变量的应用,;代码段mov dl,bvar1
15、;DL100dec bvar2+1;bvar2+14mov abc+3,dl;abcabcdmov ax,word ptr dvar;取双字到DX.AXmov dx,word ptr dvar+2add ax,word ptr dvar+4;加双字到DX.AXadc dx,word ptr dvar+6mov word ptr dvar+8,ax;保存双字的求和结果mov word ptr dvar+10,dx,(3) 变量的定位,汇编程序按照指令的先后顺序一个接着一个分配存储空间定位伪指令ORG控制数据或代码所在的偏移地址ORG 参数ORG伪指令是将当前偏移地址指针指向参数表达的偏移地址。例
16、如:ORG 100h ;从100H处安排数据或程序ORG $+10 ; 偏移地址加10,即跳过10个字节空间汇编语言程序中,符号“$”表示当前偏移地址值,地址计数器$,汇编程序有一个当前位置计数器,用来记录正在汇编的数据或指令目标代码存放在当前段内的偏移量。 $表示位置计数器的当前值。例如:BLOCK DB HelloNUM EQU $-BLOCK,名字和标号的属性,名字和标号是用户自定义的标识符。名字指向一条伪指令,标号指向一条指令。名字和标号一经使用便具有两类属性: 逻辑地址名字和标号对应存储单元的逻辑地址,含有段地址和偏移地址; 类型变量名的类型可以是BYTE、WORD和DWORD等;标
17、号、段名、子程序名的类型可以是NEAR和FAR,分别表示段内或段间调用汇编程序提供操作符,以便获取这些属性值,(1) 地址操作符,地址操作符取得名字或标号的段地址和偏移地址,举例,; 数据段BUFFER DB ?; 代码段MOV BX, OFFSET BUFFER MOV BX, SEG BUFFER,LEA BX, BUFFER,(2) 类型操作符,类型操作符对名字或标号的类型属性进行设置类型名 PTR 变量/标号 其中类型名可以是BYTE、WORD、DWORD, 或者是NEAR、FAR操作符SHORT 标号 对变量:LENGTH 操作符获知某变量名指向多少个数据项,只与变量定义伪指令后的第
18、一个参数有关,如果为“n DUP” 则为n,否则为1。SIZE 操作符获知它共占用多少字节空间,SIZE=LENGTH*TYPETYPE 操作符获取变量类型值。对变量而言,返回值为1(DB)、2(DW)、4(DD)、8(DQ)、10(DT);对于标号-1(NEAR)、-2(FAR),举例,; 数据段BUFFER DW ?STRING DB Hello, 10 DUP(?)RESULT DB 10 DUP(1,?); 代码段MOV BX, TYPE BUFFERMOV BX, TYPE STRING MOV BX, TYPE RESULT,; (BX)=2,; (BX)=1,; (BX)=1,举
19、例,; 数据段BUFFER DW ?STRING DB Hello, 10 DUP(?)RESULT DB 10 DUP(1,?); 代码段MOV BX, LENGTH BUFFERMOV BX, LENGTH STRING MOV BX, LENGTH RESULT,; (BX)=1,; (BX)=1,; (BX)=10,举例,; 数据段BUFFER DW ?STRING DB Hello, 10 DUP(?)RESULT DB 10 DUP(1,?); 代码段MOV BX, SIZE BUFFERMOV BX, SIZE STRING MOV BX, SIZE RESULT,; (BX)=
20、2,; (BX)=1,; (BX)=10,举例,;数据段STUFF DD 12345678H;代码段MOV CL, BYTE PTR STUFFMOV CH, BYTE PTR STUFF+1MOV AX, WORD PTR STUFFMOV DX, WORD PTR STUFF+2,; (CL)=78H,; (CH)=56H,; (AX)=5678H,; (DX)=1234H,低高,STUFF,段名 SEGMENT段名 ENDS,段定义语句 P111-112,(1) SEGMENT定义一个逻辑段,并给逻辑段赋予一个段名。段名符合标识符命名规则。记住不能以数字打头,不要用保留字。P111。(2
21、) 常见的段名如:CODE, DATA, STACK(3)定位类型,表明所定义的段起始边界对内存空间的要求,分四种情况(PAGE)(PARA)(WORD)(BYTE)(4)组合类型,指示段与段之间怎样连接和定位的,(PUBLIC)(COMMON)(STACK)(MEMORY)(AT)(NONE)(5)类别,是用单引号括起来的字符串,把类别相同的放在连续的存储区,可以不同名,一般为CODE, DATA, STACK,ASSUME 段寻址,格式ASSUME 段寄存器名:段名,段寄存器名:段名如 ASSUME CS:CODE,DS:DATA,SS:STACK作用明确段寄存器与逻辑段之间的关系,指定了
22、,某逻辑段应通过哪个段寄存器去寻址。并不是给段寄存器赋初值。CS寄存器是系统或执行转移指令时自动赋值的;SS寄存器,一种是系统自动赋值,即在堆栈段定义语句中选择组合类型的参数为“STACK”,则汇编时该段的段基址自动装入SS,同时SP也自动赋值,另一种是用户用MOV指令赋值;DS、ES只能有用户用MOV指令赋值。,过程定义伪指令 语句,过程名 PROC NEAR/FAR RET过程名 ENDP调用过程:CALL 过程名 注意:过程名也是过程入口的符号地址,过程类型有NEAR和FAR。NEAR过程仅供段内调用,段类型的默认值;FAR过程可供段间调用。一个过程中,至少要有一条RET指令。RET指令
23、是过程执行的最后一条指令。,伪指令小结,符号定义语句EQU = 数据定义语句DB DW DD DUP 段定义语句SEGMENT/ENDSASSUME 过程定义语句PROC/ENDP 其他ORG 定位 、$、 END(END后面会提到,结束伪指令) 常用运算符AND OR XOR NOTOFFSET SEG LENGTH SIZE TYPE PTR SHORT,程序开始,为了指明程序开始执行的位置,需要使用一个标号(例题中采用了start标识符)连接程序会根据程序起始点正确地设置CS和IP值,根据堆栈段的基址和堆栈段大小设置SS和SP值连接程序没有设置DS和ES值。程序如果使用数据段或附加段,必
24、须明确给DS或ES赋值大多数程序需要数据段,程序的执行开始应是:start:mov ax, data;data表示数据段的段地址mov ds,ax;设置DS,程序终止,应用程序执行结束,应该将控制权交还操作系统汇编语言程序设计中,有多种返回DOS的方法,但一般利用DOS功能调用的4CH子功能实现,它需要的入口参数是AL返回数码(通常用0表示程序没有错误)于是,应用程序的终止代码就是:mov ax,4c00hint 21h,汇编结束 END伪指令,汇编结束表示汇编程序到此结束将源程序翻译成目标模块代码的过程源程序的最后必须有一条END伪指令END 标号可选的“标号”参数指定程序开始执行点,连接程
25、序据此设置CS和IP值(例题中采用了start标识符),不要糊涂程序终止和汇编结束是两码事,系统功能调用方法,汇编程序提供给汇编语言程序员的功能非常有限程序员需要利用与硬件相关的基本输入和输出子程序ROM-BIOS和与硬件无关的操作系统DOS提供的系统功能模块,这两种程序驻留在内存,汇编语言程序可以直接调用。系统功能调用是程序设计的一个重要方面通过中断服务程序的方式,系统功能调用步骤,通常按照如下4个步骤进行: 在AH寄存器中设置系统功能调用号,表示中断服务程序的子程序的编号 在指定寄存器中设置入口参数 用中断调用指令( INT i8)执行功能调用 根据出口参数分析功能调用执行情况,DOS输入
26、输出功能调用,DOS利用21H号中断提供给用户近百个系统功能,主要包括设备管理、目录管理和文件管理三个方面的功能重点掌握:输入一个字符,01H号功能调用输出一个字符,02H号功能调用输出一个字符串,09H号功能调用,02H号DOS功能调用,输出一个字符 功能调用号:AH02H 入口参数:DL欲显示字符的ASCII码 功能调用:INT 21H 出口参数:无,;显示一个问号“ ?”mov ah,02h;设置功能调用号mov dl,?;设置入口参数int 21h;功能调用,例题-回车换行的子程序,crlfprocpush ax;保护寄存器push dxmov ah,2mov dl,0dh;回车功能的
27、ASCII码是0DHint 21hmov ah,2mov dl,0ah;换行功能的ASCII码是0AHint 21hpop dx;恢复寄存器pop axretcrlfendp,09H号DOS功能调用,输出一个字符串 功能调用号:AH09H 入口参数:DS:DX欲显示字符串在内存中的首地址(逻辑地址形式:DS段地址,DX偏移地址)内存中的字符串以ASCII码形式保存,最后必须添加一个“$”结尾(并不显示) 功能调用:INT 21H 出口参数:无,例题-在屏幕上显示一段信息,;数据段(定义要显示的字符串)stringdb Hello, Assembly !,0dh,0ah,$;代码段(显示字符串的
28、程序)mov dx,offset stringmov ah,9int 21h,Hello, Assembly !,01H号DOS功能调用,输入一个字符 功能调用号:AH01H 入口参数:无 功能调用:INT 21H 出口参数:AL键入字符的ASCII码书本上还有7号、10号、4c号功能调用。P38,;输入一个字符mov ah,01h;设置功能调用号int 21h;功能调用mov dl,al;使用出口参数,结束用户程序的方法,START PROC FARBEGIN: PUSH DS MOV AX, 0 PUSH AX . RETSTART ENDP,推荐采用第1种方法。,综合例题P139 例4.
29、36,顺序程序设计,没有分支、循环等转移指令的程序,会按指令书写的前后顺利依次执行,这就是顺序程序顺序结构是最基本的程序结构完全采用顺序结构编写的程序并不多见,例题,STACK SEGMENT STACK STACK ;组合类型、类别 DW 64DUP(?) ;定义堆栈段 ,见P112STACK ENDSDATA SEGMENT X DW 0010H Y DW 0123H Z DW 7890H V DW 3456H ;分配变量X、Y、Z、V QR DW ? ;存放商 REMAINDER DW ?;存放余数DATA ENDS,要求:计算(V(X*YZ540)/X,例 代码段,CODE SEGME
30、NT ASSUME CS:CODE,DS:DATA,SS:STACKMAIN PROCSTART: MOV AX,DATA MOV DS,AX ;初始化DS MOV AX,X ;AXX IMUL Y;DX:AXX*Y MOV CX,AX MOV BX,DX;暂存在BX,CX中 MOV AX,Z CWD;Z扩展,字扩展成双字,DX:AX ADD CX,AX ADC BX,DX;BX:CXX*YZ,要求:计算(V(X*YZ540)/X,例 代码段(续1),SUB CX,540 SBB BX,0;可能有借位 MOV AX,V CWD;扩展V SUB AX,CX SBB DX,BX IDIV X MO
31、V QR,AX ;保存商 MOV REMAINDER,DX;保存余数,要求:计算(V(X*YZ540)/X,例 代码段(续2),MOV AH,4CH INT 21H;程序结束,返回到DOS MAIN ENDP;过程结束 CODE ENDS;码段结束 END START;结束汇编,指定程序入口地址,举例顺序程序设计实例,data segmentASCIIdb 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h;对应0 9的ASCII码db 41h,42h,43h,44h,45h,46h;对应A F的ASCII码hexdb 04h,0bh;假设两个数据data ends
32、,采用查表法,实现一位16进制数转换为ASCII码显示,例代码段,code segmentassume cs:code, ds:datastart:mov ax, datamov ds, axmov bx, offset ASCII;BX指向ASCII码表mov al, hex;AL取得一位16进制数;恰好就是ASCII码表中的位移and al, 0fh;只有低4位是有效的,高4位清0xlat;查表:ALDS:BXAL,例代码段(续),mov dl, al;入口参数,要显示的字符DLALmov ah, 2;02号DOS功能调用int 21h;显示一个ASCII码字符mov al, hex+1;
33、转换并显示下一个数据and al, 0fhxlatmov dl, almov ah, 2int 21hmov ah, 4chint 21hcode endsend start,分支程序设计,分支程序根据条件是真或假决定执行与否判断的条件是各种指令,如CMP、TEST等执行后形成的状态标志转移指令Jcc和JMP可以实现分支控制分支结构有单分支结构双分支结构多分支结构,单分支结构,条件成立跳转,否则顺序执行分支语句体注意选择正确的条件转移指令和转移目标地址,实例:求绝对值,例计算AX中有符号数的绝对值,cmp ax,0jge nonneg;条件满足(AX0),转移neg ax;条件不满足,求补no
34、nneg:mov result,ax;条件满足,;另外一种做法,繁琐cmp ax,0jl yesneg;条件满足(AX0),转移jmp nonnegyesneg:neg ax;条件不满足,求补nonneg:mov result,ax;条件满足,双分支结构,条件成立跳转执行第2个分支语句体,否则顺序执行第1个分支语句体注意第1个分支体后一定要有一个JMP指令跳到第2个分支体后,实例:显示BX的最高位,例 显示BX的最高位,shl bx,1;BX最高位移入CF标志jc one;CF1,即最高位为1,转移mov dl,30h;0的ASCII码是30H ;CF0,即最高位为0:DL30H0jmp tw
35、o;一定要跳过另一个分支体one:mov dl,31h;DL 31H1two:mov ah,2 ;2号功能调用int 21h;显示字符,可以用JNC替换JC,例显示BX的最高位(续 用jnc),shl bx,1;BX最高位移入CF标志jnc one;CF0,即最高位为0,转移 one:mov dl,31h ;CF1,即最高位为1:DL31H1jmp two;一定要跳过另一个分支体!one:mov dl,30h;DL 30H0two:mov ah,2int 21h;显示,例 显示BX的最高位(另解),mov dl,0 ;DL30H0shl bx,1;BX最高位移入CF标志jnc two;CF0,
36、即最高位为0,转移mov dl,1 ;CF1,即最高位为1:DL31H1two:mov ah,2int 21h;显示,编写分支程序,需留心分支的开始和结束,例 显示BX的最高位(无分支),mov dl,0shl bx,1;BX最高位移入CF标志adc dl,30h;CF0,DL030h030H0;CF1,DL030h131H1two:mov ah,2int 21h;显示,例 压缩的BCD码,显示其值,无前导0,;数据段BCDdb 04h;代码段mov dl,BCDtest dl,0ffh;如果BCD码为0,显示0jz zero;如果是0,转到zero:,双分支结构test dl,0f0h;如果
37、BCD码高位为0,不显示0jz one;单分支结构,例 压缩的BCD码,显示其值,无前导0(续),mov cl,4;高4位不为0,处理高位shr dl,clor dl,30h;转换为ASCII码mov ah,2;显示高位int 21hmov dl,BCDand dl,0fhone:or dl,30h;处理低位jmp twozero:mov dl,0two:mov ah,2int 21h,多分支结构,多分支结构是多个条件对应各自的分支语句体,哪个条件成立就转入相应分支体执行,cmp ah,0jz function0cmp ah,1jz function1cmp ah,2jz function2,
38、例如果是小写字母转换成大写字母,;如果DL是一个小写字母,则转换为大写cmp dl,a;小于小写字母a,不需要处理jb dispcmp dl,z;大于小写字母z,也不需要处理ja dispsub dl,20h;是小写字母,则转换为大写disp: 大写字母 其他 小写字母 41H-5AH 61H-7AH,循环程序设计,循环程序结构是满足一定条件的情况下,重复执行某段程序循环结构的程序通常有3个部分(3要素): 循环初始部分为开始循环准备必要的条件,如循环次数、循环体需要的数值等 循环体部分指重复执行的程序部分,其中包括对循环条件等的修改程序段循环控制部分判断循环条件是否成立,决定是否继续循环,关
39、键是什么?,循环控制,循环结构程序的设计关键是循环控制部分循环控制可以在进入循环之前进行,也可以在循环体后进行,于是形成两种结构:“先判断、后循环”结构“先循环、后判断”结构循环结束的控制可以用循环次数,还可以用特定条件等,于是又有:计数控制循环条件控制循环,先循环后判断的循环结构,计数控制循环,计数控制循环利用循环次数作为控制条件易于采用循环指令LOOP和JCXZ实现初始化:将循环次数或最大循环次数置入CX循环体循环控制:用LOOP指令对CX减1,并判断是否为0,例-用二进制显示BL内容(逐位显示),mov cx,8;CX8(循环次数)again:shl bl,1;左移进CF,从高位开始显示
40、mov dl,0;MOV指令不改变CFadc dl,30h;DL030HCF ;CF若是0,则DL 0 ;CF若是1,则DL 1 mov ah,2int 21h;显示loop again ;CX减1,如果CX未减至0,则循环,计数控制循环先循环后判断,例-求最大最小值,在16位带符号数中找出其中的最大值和最小值,分别放在MAX和MIN单元中。,again,next1,next2,BX-存储单元地址AX-最大值DX-最小值CX-循环次数,例-求最大最小值(续),DATA SEGMENTBUFFER DW 100DUP(?);自定义N个数COUNT EQU $-BUFFER ;字节距离MAX DW
41、 ?;保存最大值MIN DW ?;保存最小值DATA ENDSCODE SEGMENTASSUME CS:CODE, DS:DATA,定义数据,例-求最大最小值(续),START:MOV AX, DATAMOV DS, AX ;数据段寄存器赋值MOV CX, COUNTSHR CX, 1 ;计算字的个数 字节数除以2LEA BX, BUFFERMOV AX, BX ;AX最大值初值 MOV DX, BX;DX最小值初值 DEC CX ;循环次数减1,共比较n-1次,初始化,例-求最大最小值(续),AGAIN:ADD BX, 2 ; 指向下一个数字CMP AX, BX ;比较JGE NEXT1M
42、OV AX, BX ;AX取得更大的数据JMP NEXT2NEXT1: CMP DX, BXJL NEXT2MOV DX, BX;BX取得更小的数据NEXT2:LOOP AGAIN ;计数循环MOV MAX, AX ;保存最大值MOV MIN, DX ;保存最小值MOV AH, 4CHINT 21HCODE ENDSEND START,循环体,again,next1,next2,条件控制循环,条件控制循环需要利用特定条件判断循环是否结束条件控制循环用条件转移指令判断循环条件转移指令可以指定目的标号来改变程序的运行顺序,如果目的标号指向一个重复执行的语句体的开始或结束,便构成了循环控制结构,例-
43、显示以0结尾的字符串,;数据段stringdb Let us have a try !,0;代码段mov bx,offset stringagain:mov dl,bxcmp dl,0jz done;为0结束mov ah,2;不为0,显示int 21hinc bx;指向下一个字符jmp againdone:,条件控制循环先判断后循环,例- 记录某个字存储单元数据中1的个数,;数据段numberdw 1110111111100100B;代码段mov bx,numberxor dl,dl;循环初值:DL0again:cmp bx,0;也可以用test bx,0ffffhjz done ;全部是0就可以退出循环,减少循环次数shl bx,1;用指令shr bx,1也可以adc dl,0;利用ADC指令加CF的特点进行计数jmp again,