0

;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
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
user1598734
  • 15
  • 1
  • 1
  • 4

2 Answers2

2

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
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Welcor
  • 2,431
  • 21
  • 32
0

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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • ;Now My readwrite BLOCK looks something like this ;But this does not seem to work ? Do you have any idea ? readwrite: ;Top of read/write loop mov AH, 01h ;Get ready to read a character int 21h ;Read character into AL mov bl, al sub bl, 'a' cmp bl, 26 ja not_lower not_lower: sub al, 20h 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 – user1598734 Oct 13 '12 at 01:20
  • ;This is my final solution to the Thing but it converts both upper ;and lower case, the condition is not helping readwrite: ;Top of read/write loop mov AH, 01h ;Get ready to read a character int 21h ;Read character into AL cmp al, 'a' jg not_lower cmp al, 'z' jl not_lower sub al, 20h not_lower: ;Converting to Upper Case if Lower Case is Entered sub al, 20h 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 – user1598734 Oct 13 '12 at 02:06
  • @user1598734: Sorry, but I can't decipher the code when it's strung together in a comment like this. – Jerry Coffin Oct 13 '12 at 03:48
  • Related: [How to access a char array and change lower case letters to upper case, and vice versa](https://stackoverflow.com/a/35936844) for more details about the unsigned-compare trick. Also, you could `lea ebx, [rax-'a']` instead of mov/sub, but I guess this is a 16-bit question. – Peter Cordes Aug 17 '18 at 10:47