汇编语言大小写转换的问题

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码列出来,进行一下对比,从中找到规律。

511遇见

通过对比,我们可以看出来,小写字母的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

发布日期:

所属分类: 易语言 标签: