;I created this program (Intel 8086 Assembly) to read characters and store them and print ;them in reverse order after converting them to Upper Case. I know you can convert to upper ;case using (sub AL, 20h) but how do I put the conditional (IF) Loop ?
org 100h
mov BX, 0800h
mov DS, BX ;Set segment register
mov BX, 0000h ;Set offset register
mov CX, 0 ;Set counter to 0
;mov CH, 0
readwrite: ;Top of read/write loop
mov AH, 01h ;Get ready to read a character
int 21h ;Read character into AL
;jb readwrite
mov [BX], AL ;Move AL into memory at DS:BX
add CX, 1 ;Increment Counter
add BX, 1 ;Increment offset
cmp AL, '$' ;Compare entered to $
jg readwrite ;if (C > 0) loop
;Reverse Printing
mov BX, 0800h
mov DS, BX ;Set segment register
mov BX, 0000h ;Set offset register
add BX, CX
sub BX, 2
mov AH, 0eh
mov AL, 010 ;NL
int 10h
mov AL, 013 ;CR
int 10h
revprinting:
mov AL, [BX]
int 10h
sub BX, 1
sub CX, 1
cmp CX, 1
jg revprinting
ret
If you know your bytes are alphabetic (not 0..9
or other non-letters), you can skip the IF-Part.
Instead of using 20h
as the difference between upper case and lower case in ASCII, you unconditionally set or clear Bit Nr. 5 (ASCII-character: Bit Nr. 7, ... , Bit Nr. 0).
By setting Bit 5 of an ASCII-character to 1, you get a lower case letter. By setting Bit 5 to 0, you get the upper case letter. (http://asciitable.com/)
Get upper case. Clear Bit 5 to 0 by ANDing with a mask that has all the other bits set:
and al, 0xdf ; you may use 0dfH instead of 0xdf in your notation, or ~0x20
Get lower case. Set Bit 5 to 1:
or al, 0x20 ; 20h
This can be useful to check whether a character is a letter or not as well. You simply set all letters to upper case. After that you check with "cmp" whether the character is below 'A' or above 'Z'. If not, then it is a letter. Or even better,
and al, 0xdf ; force uppercase (if it was a letter to start with)
sub al, 'A' ; letters turn into AL in [0..25]
cmp al, 'Z'-'A'
ja non_letter ; unsigned compare: lower ASCII codes wrap to high values
To do the conversion conditionally, you'd typically use a couple of comparisons:
cmp al, 'a'
jl not_lower
cmp al 'z'
jg not_lower
sub al, 20h
not_lower:
Depending on the situation, there's another possibility that can be preferable:
mov bl, al
sub bl, 'a'
cmp bl, 'z'-'a' ; 25
ja not_lower
sub al, 20h
not_lower:
Lets you get by with only one jmp instead of two, and helps make it a bit more predictable.