下面考虑这样一个问题,在codesg中填写代码,将datasg中的第一个字符串转化为大写,第二个字符串转化为小写。
assume cs:codesg,ds:datasg datasg segment db'BaSiC' db'iNfOrMaTiOn' datasg ends codesg segment start: codesg ends end start
首先分析一下,我们知道同一个字母的大写字符和小写字符对应的ASCII码是不同的,比如“A”的ASCII码是41H, "a”的ASCII码是61H。要改变一个字母的大小写,实际上就是要改变它所对应的ASCII码。我们可以将所有的字母的大写字符和小写字符所对应的ASCII码列出来,进行一下对比,从中找到规律。
通过对比,我们可以看出来,小写字母的ASCII码值比大写字母的ASCII码值大20H。这样,我们可以想到,如果将“a”的ASCII码值减去20H,就可以得到“A";如果将“A”的ASCII码值加上20H就可以得到“a"。按照这样的方法,可以将datasg段中的第一个字符串“BaSiC”中的小写字母变成大写,第二个字符串“iNfOrMaTiOn”中的大写字母变成小写。
要注意的是,对于字符串“BaSiC",应只对其中的小写字母所对应的ASCII码进行减20H的处理,将其转为大写,而对其中的大写字母不进行改变:对于字符串"iNfDrMaTiOn",我们应只对其中的大写字母所对应的ASCII码进行加20H的处理,将其转为小写,而对于其中的小写字母不进行改变。这里面就存在着一个前提,程序必须要能够判断一个字母是大写还是小写。以“BaSiC”讨论,程序的流程将是这样的:
assume cs:codesg,ds:datasg datasg segment db'BaSiC' db'iNfOrMaTiOn' datasg ends codesg segment start:mov ax,datasg mov dx,ax mov bx,0 mov cx,5 s: mov al,[bx] 如果(al)>61h,则为小写字母的ASCII码,则,sub al,20h mov [bx],al inc bx loop s . . . codesg ends end start
判断将用到一些我们目前还没有学习到的指令。现在面临的问题是,用己学的指令来解决这个问题,则不能对字母的大小写进行任何判断。
但是,现实的问题却要求程序必须要能区别对待大写字母和小写字母。那么怎么办呢?
如果一个问题的解决方案,使我们陷入一种矛盾之中。那么,很可能是我们考虑问题的出发点有了问题,或是说,我们起初运用的规律并不合适。
我们前面所运用的规律是,小写字母的ASCII码值,比大写字母的ASCII码值大20H。考虑问题的出发点是:大写字母+20H=小写字母,小写字母一20H=大写字母。这使我们最终落入了这样一个矛盾之中:必须判断是大写字母还是小写字母,才能决定进行何
种处理,而我们现在又没有可以使用的用于判断的指令。
我们应该重新观察,寻找新的规律。可以看出,就ASCII码的二进制形式来看,除第5位(位数从。开始计算)外,大写字母和小写字母的其他各位都一样。大写字母ASCII码的第5位为0,小写字母的第5位为I。这样,我们就有了新的方法,一个字母,不管它原来是大写还是小写,将它的第5位置0,它就必将变为大写字母:将它的第5位置1,它就必将变为小写字母。在这个方法中,我们不需要在处理前判断字母的大小写。比如:
对于“BaSiC”中的“B",按要求,它己经是大写字母了,不应进行改变,将它的第5位设为0,它还是大写字母,因为它的第5位本来就是Oa 用什么方法将一个数据中的某一位置0还是置1?当然是用我们刚刚学过的or和and指令。
完整的程序如下。
assume cs:codesg,ds:datasg datasg segment db'BaSiC' db'iNfOrMaTiOn' datasg ends codesg segment start:mov ax,datasg mov dx,ax ;设置ds指向datasg段 mov bx,0 ;设置(bx)=O,ds:bx指向,'BaSiC',的第一个字母 mov cx,5 ;设置循环次数5,因为,BaSiC,有5个字母 s: mov al,[bx] ;将A5C工工码从ds:bx所指向的单元中取出 and al,110111111B ;将a工中的ASCII码的第5位置为0,变为大写字母 mov [bx],al ;将转变后的ASC工工码写回原单元 inc bx ;(bx)加1,ds:bx指向下一个字母 loop s mov bx,5 ;设置(bx)=5,ds:bx指向,iNfOrMaTiOn'的第一个字母 mov cx,11 ;设置循环次数11,因为,iNfOrMaTiOn'有11个字母 s0 mov al,[bx] or al,00100000B ;将a工中的ASC工工码的第5位置为1,变为小写字母 mov [bx],al inc bx loop s0 mov ax,4c00h int 21h codesg ends end start