Converting Lower Case to Upper case in Intel 8086

2019-08-17 06:23发布

问题:

;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

回答1:

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


回答2:

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.