I am trying to make a program where the user have to enter a string and get an reversed output. Moreover, it should change all lowercase letters to uppercase and uppercase to lowercase. I've already done program where you can enter 1 character. My next goal is to get as many characters as I want.
I did some research and came up with this code:
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
Now I am getting a wrong output. For example if you enter Hello
it will return olleHh
. I am completely confused since I can't figure out my error. Also, I am new in Assembly. The output that I expect is OLLEh
.
Working Code:
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
You are making it complex.
First you display all the letters of your string in reverse order with the following code:
and then you try to flip the cases with the following code:
Problem is with using 0EH service of INT 10H
Why do you get that extra h letter at the end of your output string ?
You are using INT 10h which is used for video services and the service 0EH of INT 10h writes the specified character in AL to the current cursor position. Since the last character in AL was capital H in your example and which was flipped to lower case h by your code. That is where you get that extra h at the end of your output string.
Why don't you get all the letters flipped ?
Since the service 0EH of INT 10h writes only one character to the screen (not the string) you get only H to be flipped.
Solution:
You could have simply flipped the cases and displayed the reverse string in one go and that without using INT 10h.
Here is a simple code which is well documented and that does the job:
And as @Ped7g said you should use comment in your program because that explain what you are trying to do in your program and makes it easy for people to debug it.