《第12章表的处理讲解材料》由会员分享,可在线阅读,更多相关《第12章表的处理讲解材料(75页珍藏版)》请在金锄头文库上搜索。
1、第12章 表的处理,12.1 定义表 12.2 表的直接存取 12.3 表的搜索 12.4 转换指令XLAT 12.5 显示十六进制数和对应的ASCII字符 12.6 数据排序程序 12.7 TYPE、LENGTH和SIZE运算符,12.1 定 义 表,为了便于对表的处理,首先要定义表,组织好表的结构,即把表的内容按一定规律组织起来。这样编程时就可以根据一定规律存取表中各项的内容。表的定义、组织没有固定的方法,完全是按表的内容和用途而定。表的元素(内容)可以是一个数,也可以是一个字符或字符串。,例如:以英文月份的缩写定义一个表,可以是如下的格式: MONTAB DBJAN, FEB, MAR,
2、DEC 这个表具有连续、数据项等长的特点,处理起来就很方便。只要指定月份,就很容易查出该月的英文月份的缩写。,12.2 表的直接存取,假设使用者从键盘输入一个月份的号码,如03,程序负责把它转换成文字型的月份名称的缩写MAR。完成这个工作的程序,必须定义一个表以存放各月份的名称,要求表中的每一项长度一样(即3)。所以这个表必须定义为下列形式:,表中的第一项JAN的偏移地址是MONTAB0,FEB的偏移地址是MONTAB3,MAR的地址是MONTAB6。为了找到3月份在表中的月份缩写名称,程序必须做下列操作: (1) 输入月份3的ASCII码33,33转换成二进制的3。 (2) 从月份中减去1:
3、3-12。 (3) 将差值乘以3(月份字符长度):236。,(4) 将所得的乘积加到MONTAB的偏移地址:MONTAB6,结果即为3月份MAR的偏移地址。 下例是完成上述工作的程序。,例12.1 从键盘输入一个数字月份,显示其对应的英文缩写。 源程序清单如下: ; filename:L121. ASM ; DATA SEGMENT THREE DB 3 MONIN DB 11 ;假设已输入的月份,ALFMON DB ?, $ MONTAB DB JAN, FEB, MAR, APR, MAY, JUN DB JUL, AUG, SEP, OCT, NOV, DEC DATA ENDS ; C
4、ODE SEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA START: MOV AX,DATA,MOV DS,AX MOV ES,AX CALL C10CONV CALL D10LOC CALL F10DISP MOV AH,4CH INT 21H ; ASCII码转换成二进制 ; ,C10CONV PROC MOV AH,MONIN MOV AL,MONIN+1 XOR AX,3030H CMP AH,00,JZ C20 SUB AH,AH ADD AL,10 C20: RET C10CONV ENDP ; Locate month table ; D10LOC
5、PROC,LEA SI,MONTAB DEC AL ;月份减1 MUL THREE ADD SI,AX ;形成该月英文的首地址 MOV CX,03 CLD LEA DI,ALFMON REP MOVSB ;传送3个字符 RET,D10LOC ENDP ; Display alpha month ; F10DISP PROC LEA DX,ALFMON MOV AH,09 ;显示月份英文缩写 INT 21H RET F10DISP ENDP CODE ENDS END START,说明:例12.1假设使用者已用另外一个程序接受了输入的ASCII月份数,并存在MONIN单元内。 如果上述各数据项长
6、度不等长,那么取出中间数据项就很麻烦。例如,要求显示英文月份全名,此时需要构造有规律的表;方法是取最长月份的名作为各月份项的长度,不足者补空格,然后就可按照上述方法处理编写程序。,因为例12.1的方法是直接计算表中的某项地址,然后存取,而不需要将整个表从头到尾搜寻一遍,所以称为表的直接存取法。 直接存取法虽然很有效,但是它只适用于各项连续的表;例如,表的各项是1,2,3 的顺序,或606,607,608,甚至可以是5,10,15 。但是,通常实际使用时不会全是有如此规律的表。,12.3 表 的 搜 索,表的搜索方法有直接搜索法、顺序搜索法、折半搜索法等。 直接搜索法就是要搜索的内容和它在表中的
7、位置存在有一定的规律,也就是说可用某一公式表示获得这种规律。这种方法搜索最快,但要求表中各数据项有规律性。在定义表时尽量要满足某种规律,然后才能使用,见例12.1。,顺序搜索法通常适用于对无规律的数组进行搜索,表中的元素之间或元素与地址之间无规律可循。此种方法只能从表的开头开始逐项搜索,这种方法的平均比较次数为(n+1)/2次,所以速度慢,效率低。 折半搜索法适用于已排序的表,这种方法搜索次数少,效率高。,例12.2 顺序搜索表。设有一个包含若干个字节的数组,首地址为A;要求编写程序,查找其中是否存在数“8”。若存在,显示“Y”;否则,显示“N”。 源程序清单如下:,; filename:L1
8、22.ASM ; DATA SEGMENT A DB 1,3,20,5,6,2,8 CEQU $A,DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA START: MOV AX,DATA MOV DS,AX MOV ES,AX MOV CX,C LEA DI, A MOV AL,8 CLD,REPNZSCASB JZ FOUND MOV DL,N JMP DISP FOUND:MOVDL,Y DISP:MOV AH,2 INT 21H MOV AH,4CH INT 21H CODE ENDS END START,例12.3 对元素长度超
9、过两个字节的表进行搜索。 当表中各项的长度超过两个字节时,就必须用REPE CMPS指令来比较。假设,有这样一种货物号与货物名表:3个字节长度的货物号,9个字节长度的货物名,见例12.3数据段。STOKNIN是数据段的第一栏,表示要搜寻的货物号;STOKTAB是第二栏,表示货物表的开始,它们在存储器中的排列情形如下: 货物表: 123 035 Excavators 038 Lifters 049 Presses 偏移地址: 00 03 06 16 19 29 32,表的最后使用了一项“999”作为搜寻结束的标识。表中的每一项内容以下列的方法与STOKNIN作比较: 表中之项 STOKNIN 比
10、较结果 035 123 小于,检查下一项 038 123 小于,检查下一项 049 123 小于,检查下一项 102 123 小于,检查下一项 123 123 等于,搜索成功,例12.3的程序所使用的CMPSB指令,可以一个字节一个字节逐个比较,直到不相等为止,同时它也可以将寄存器SI和DI自动加1。 首先,CX被初始化为03,而SI和DI所存的偏移地址分别是03和00。当表中的第一项和STOKNIN比较时(035:123)会在第一个字节比较完之后结束;此时SI是04,DI是01,而CX是02。为了能正常地进行下一项的比较,SI应该是16,DI应该是00。,要获得正确的DI内容,可以再将STO
11、KNIN的地址传送给DI;若要使SI能得到正确的地址,它应由上一次比较停在哪一项之后而决定;还应考虑CX当前的值,即有多少字节未作比较,此时CX是02。SI的当前值加上CX的当前值再加上货物名的长度,就可以得到下一项在表中的正确地址,即 CMPSB执行后SI内的值: 04 加CX的当前值: 02 加货物名的长度: + 10 下一项的偏移地址: 16,由于CX所含的值是剩下的未作比较的字节数,所以,以上的计算方法适用于所有的情形。在比较了1、2或3个字节之后,当比较的结果相等时,CX的值是00,此时SI也就是所要的货物名的地址了。 例12.3的源程序清单如下: ; filename:L123.A
12、SM ; DATA SEGMENT STOKNIN DB 123,STOKTAB DB 035, Excavators ;Start of table DB 038, Lifters DB 049, Presses DB 102, Valves DB 123, Processors DB 127, Pumps DB 999, 10 DUP( ) ;End of table DESCRN DB 10 DUP(?),DATA ENDS ; CODE SEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA START: MOV AX,DATA MOV DS,AX MOV ES,
13、AX CLD LEA SI,STOKTAB A20: MOV CX,03,LEA DI,STOKNIN REPE CMPSB JE A30 JA A40 ADD SI,CX ADD SI,10 JMP A20 A30: MOV CX,05 LEA DI,DESCRN REP MOVSW JMP A50,A40: CALL R10ERR A50: MOV AH,4CH INT 21H ; R10ERR PROC ; RET R10ERR ENDP CODE ENDS END START,12.4 转换指令XLAT,XLAT指令可以将一个字节的值,转换成另一个已经预先定义在一个表中的值。例如,可以
14、利用XLAT指令把十六进制数转换成其对应的ASCII码,或把ASCII码转换成十六进制数。,例12.4是把十六进制数(Hex)转换成ASCII码。要使用XLAT指令,必须先定义一个转换表,用以存放十六进制数对应的ASCII码表,如: XLTAB DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H,在使用XLAT指令之前,要先将表格的首地址放入BX寄存器内,要转换的字节即 十六进制数,也应预先放入AL寄存器中;指令执行后可在AL中得到转换后的代码(ASCII码)。XLAT指令利用AL寄存器内的值当作相对位移值
15、,再加上BX的值,即可得到正确的地址。假设Hex是5,那么计算所得的地址是XLTAB5,XALT根据这个地址从表中查得35H,取代了AL原先的5。所以这种方法被称为查表法。,例12.4 用查表法将一位十六进制数转换成相应的ASCII码。 源程序清单如下:,; filename:L124.ASM ; DATA SEGMENT,XLTAB DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H HEX DB 5 ASC DB ? DATA ENDS ; CODE SEGMENT,ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOVDS,AX LEA BX,XLTAB MOVAL,HEX XLAT MOV ASC,AL MOV AH,4CH INT 21H