输入一个字符串,拉丁文小写字母变成大写字母,其余字符只切换回二进制代码和显示的偶数位数。
本条例
DOSSEG ;segment sequencing directive
.MODEL SMALL ;directive of the model of code
;and data of the near type
.STACK 200H ;a 512-byte stack
.DATA ;start of the data
STRING DB 'c~cbd$' ;string
STRING_LENGTH EQU $-STRING ;string length=6 in this example
STRING1 DB STRING_LENGTH DUP (?) , '$' ;another string1,has the same
;length
.CODE ;start of the code
MOV AX,@DATA ;access to the data segment
MOV DS,AX ;access to the data segment
XOR SI,SI ;SI set to zero
XOR DI,DI ;DI set to zero
MOV CX,STRING_LENGTH ;put string length into CX,for
;looping 6 times
S: ;breakpoint S
MOV BL,STRING[DI] ;remember current element of
;string into BL
AND STRING[DI],11100000B ;checking if the current element
;of string is lowercase
CMP STRING[DI],01100000B ;checking if the current element
;of string is lowercase
JNE L1 ;if the current element of string
;is lowercase is not equal
; go to the breakpoint L1 otherwise go to inside
XOR BL,00100000B ;remember current element of string into BL
; (lowercase letters) convert to capital letters
MOV STRING1[SI],BL ;put the current capital letter into string1
ADD SI,2 ;increment by 2 (because the size of SI is 2 bytes)
; to go to the next item of string1
ADD DI,2 ;increment by 2 (because the size of DI is 2 bytes)
;to go to the next item of string
LOOP S ;cycle,go to the breakpoint S
L1: ;breakpoint L1
XOR STRING[DI],01010101B ;Switch the current element of string back
;to only non-even places
MOV AL,STRING[DI] ;put the current element into register AL
MOV STRING1[SI],AL ;put the current element into string1
ADD SI,2 ;increment by 2 (because the size of SI is 2 bytes)
; to go to the next item of string1
ADD DI,2 ;increment by 2 (because the size of DI is 2 bytes)
; to go to the next item of string
LOOP S ;cycle,go to the breakpoint S
XOR DX,DX ;DX set to zero
LEA DX,STRING1 ;download executive address
MOV AH,09H ;DOS line output function
INT 21H ;display changed characters
MOV AH,4CH ;DOS function of program termination
INT 21H ;finish the program
END
我使用TURBODEBBUGER看看什么是抢夺但是无法找到问题
我在谷歌流行搜索,谷歌但无法找到当前的问题。 你可以帮助我解决这个问题吗?
答案 0 :(得分:3)
我认为你想要的基本上是这样的主循环:
... (set DS, etc)
mov cx,STRING_LENGTH
xor si,si
processString:
; si = index of character to process
; cx = characters to process
mov al,STRING[si] ; al = source character
cmp al,'a'
jb not_lowercase_letter
cmp al,'z'
ja not_lowercase_letter
; lowercase letter in AL detected, make it capital
and al,11011111B ; clear the 0x20 bit
jmp store_final_character
not_lowercase_letter:
xor al,01010101B ; flip the bits on odd positions
store_final_character:
mov STRING1[si],al
inc si
loop processString
... (output result)
您应该从这段代码中学到什么(如果您设法使其成功):
只有在无法避免存储器时才访问存储器,即字符值从STRING加载一次,并写入STRING1一次。从来没有像XOR STRING[SI],55h
这样的指令,然后用这样的记忆值进一步操纵。内存访问比仅在寄存器上执行的操作慢得多,因此只要您有多个操作要做,通常最好将值从内存移动到寄存器中,对其进行所有计算,然后存储最终结果回到记忆中。
因为STRING在1:1映射中转换为STRING1(一个输入字符确实产生一个输出字符),我只使用si
中的一个索引,而不是{{1}中的两个相同索引} + si
。
我正好测试拉丁文小写字母(' a'到' z'值范围),你的位掩码测试可能会误认为像{{1}这样的字符}对于小写字母,请参阅ASCII表定义以了解字符的编码方式,并对其中一些字符进行测试计算,以了解它们的结果。
我有循环体开头和结尾的单一代码路径。我使用小写字母代码路径中的di
来跳过非小写的中间部分,然后重新加入到存储修改后的字符的共享代码中。这使我免于存储结果和递增索引的重复行以及两条{
指令。
使用有意义的标签名称。 jmp
并不意味着什么,对其他源代码读者来说,它会变得非常神秘和难以理解。由于IBM PC计算机使用640kB的基本RAM,因此不需要使用短标签来节省内存,就像我们在具有16-64kB RAM的8位计算机上所做的那样,只需将汇编程序+源代码+编译结果安装到内存中相当成就,并且经常将源代码分成几个较小的部分,分别编译,然后在测试它们之前,你必须从内存中删除汇编器和源代码并加载已编译的机器代码。 (这是1988年的声音,今天你有GIGA字节的内存,你将永远不会在你的整个生命中编写足够长的源代码,甚至可以轻微地填充当前的计算机RAM)。因此,如果1988年已经可以使用有意义的标签名称,那么今天也可以使用它们。