我正在尝试创建一个程序,用户必须输入一个字符串并获得反向输出。此外,它应该将所有小写字母更改为大写,大写更改为小写。我已经完成了可以输入1个字符的程序。我的下一个目标是获得尽可能多的角色。
我做了一些研究并提出了这个代码:
org 100h
include emu8086.inc
.DATA
STR1 DB 0DH,0AH, 'Input: $'
STR2 DB 0DH,0AH, 'Output: $'
nl db 0dh,0ah,'$'
.CODE
START:
MOV AX, @DATA
MOV DS, AX
cmp al, 0x41h
JGE IsInLowerCaseRange
Disp:
LEA DX,STR1
MOV AH,09H
INT 21H
MOV CL,00
MOV AH,01H
Read:
INT 21H
MOV BL,AL
PUSH BX
inc cx
CMP AL,0DH
JZ DISPLAY
JMP READ
Display:
LEA DX,STR2
MOV AH,09H
INT 21H
lea dx, nl
mov ah,09h
int 21h
ANS:
MOV AH,02H
POP BX
MOV DL,BL
INT 21H
LOOP ANS
IsInLowerCaseRange:
cmp al, 0x5Ah
jle DisplayLowerCaseLetter
cmp al, 0x61h
jge IsInUpperCaseRange
jmp NotALetter
DisplayLowerCaseLetter:
add al, 0x20h
mov ah, 0xEh
int 10h
jmp exit
IsInUpperCaseRange:
cmp al, 0x7Ah
jle DisplayUpperCaseLetter
jmp NotALetter
DisplayUpperCaseLetter:
sub al, 0x20h
mov ah, 0xEh
int 10h
jmp exit
NotALetter:
printn
print "The input character is not a letter."
exit:
hlt
.EXIT
END START
现在我得到了错误的输出。例如,如果输入Hello
,它将返回olleHh
。我完全困惑,因为我无法弄清楚我的错误。另外,我是大会的新人。我期待的输出是OLLEh
。
工作守则:
org 100h
include emu8086.inc
.DATA
STR1 DB 0DH, 0AH, 'Input: $'
STR2 DB 0DH, 0AH, 'Output: $'
Nl DB 0Dh, 0Ah,'$'
.CODE
START:
MOV AX, @DATA
MOV DS, AX
DISP:
LEA DX,STR1
MOV AH,09H
INT 21H
MOV CL,00
MOV AH,01H
READ:
INT 21H
MOV BL, AL
PUSH BX
INC CX
CMP AL, 0DH
JZ DISPLAY
CMP AL, 'A' ; < then A
JB NotALetter
CMP AL, 'Z' ; > then Z
JA AGAIN ; repeat again
JMP CONTINUE1
AGAIN:
CMP AL, 'a' ; < then a
JB NotALetter
CMP AL, 'z' ; > then z
JA NotALetter
CONTINUE1:
JMP READ
DISPLAY:
LEA DX, STR2
MOV AH, 09h
INT 21H
LEA DX, NL
MOV AH, 09h
INT 21h
POP BX ; pop enter key
ANS:
MOV AH, 02h
POP BX ; pop the character
CMP BL, 'a' ; check if its in upper case
JB toLower ; if yes then jmp to toLower
SUB BL, 32 ; if not in upper case then convert to upper case
JMP CONTINUE2
toLower:
ADD BL, 32 ; convert to lower case
; Probably have to subtract 32 if BL = 20h
CONTINUE2:
MOV DL, BL
INT 21H
LOOP ANS
JMP EXIT ; if everything is fine jmp to exit
NotALetter:
printn
print "The input character is not a letter."
EXIT:
hlt
.EXIT
END START
你让它变得复杂。
首先,使用以下代码以相反的顺序显示字符串的所有字母:
ANS:
MOV AH,02H
POP BX
MOV DL,BL
INT 21H
LOOP ANS
然后您尝试使用以下代码翻转案例:
IsInLowerCaseRange:
cmp al, 0x5Ah
jle DisplayLowerCaseLetter
cmp al, 0x61h
jge IsInUpperCaseRange
jmp NotALetter
DisplayLowerCaseLetter:
add al, 0x20h
mov ah, 0xEh
int 10h
jmp exit
IsInUpperCaseRange:
cmp al, 0x7Ah
jle DisplayUpperCaseLetter
jmp NotALetter
DisplayUpperCaseLetter:
sub al, 0x20h
mov ah, 0xEh
int 10h
问题在于使用INT 10H的0EH服务
为什么在输出字符串的末尾会得到额外的h字母?
您正在使用用于视频服务的INT 10h,并且INT 10h的服务0EH将AL中的指定字符写入当前光标位置。由于AL中的最后一个字符在您的示例中是大写字母H,并且您的代码将其翻转为小写字母h。这就是你在输出字符串末尾获得额外h的地方。
你为什么不把所有的字母翻过来?
由于0EH的服务INT 10h只在屏幕上写入一个字符(而不是字符串),因此只能翻转H。
解:
您可以简单地翻转案例并一次性显示反向字符串,而不使用INT 10h。
这是一个简单的代码,有很好的文档记录,可以完成工作:
org 100h
.DATA
str1 db 10,13, 'Input: $'
str2 db 10,13, 'Output: $'
errMsg db 10,13, 'The input character is not a letter.$'
.CODE
START:
mov ax, @DATA
mov ds, ax
mov dx, offset str1
mov ah, 09h
int 21h
mov cl,00
mov ah,01h
mov bx, '#' ; store some random character
; into stack to remeber when to stop
push bx ; poping the character while diplaying
Read:
int 21h
cmp al, 13 ; check if enter key is pressed
je DISPLAY ; if yes then display the letters if any
cmp al, 'A' ; check if ASCII value of inputted charater is less than ASCII value of capital A
jb NotALetter ; if yes then print "no a letter"
cmp al, 'Z' ; check if ASCII value of inputted charater is not greater than ASCII value of capital Z
jna letterFound ; if not then continue
cmp al, 'a' ; check if ASCII value of inputted character is less than ASCII value of small a
jb NotALetter ; if yes then print "no a letter"
cmp al, 'z' ; check if ASCII value of inputted character is greater than ASCII value of small z
ja NotALetter ; if not then continue
letterFound:
mov bl, al
push bx ; store the letter in stack
jmp READ
Display:
mov dx,offset str2
mov ah,09h
int 21h
ANS:
pop bx
cmp bl, '#' ; check if no more letter are available in stack
je exit
mov ah, 02h
cmp bl, 'a' ; check if the letter is in upper case
jb toLower ; if yes then jmp to toLower
sub bl, 32 ; if not in upper case then convert to upper case
jmp continue
toLower:
add bl, 32 ; convert to lower case
continue:
mov dl, bl
int 21h
jmp ans
NotALetter:
mov ah, 09h
mov dx, offset errMsg ; display error message
int 21h
exit:
mov ah, 04ch
int 21h
END START
正如@ Ped7g所说,你应该在你的程序中使用注释,因为它解释了你在程序中尝试做什么,并使人们可以轻松地调试它。