0

;我创建了这个程序(Intel 8086 Assembly)来读取字符并存储它们并在将它们转换为大写字母后以相反的顺序打印它们。我知道您可以使用 (sub AL, 20h) 转换为大写;但是如何放置条件(IF)循环?

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
4

2 回答 2

2

如果您知道您的字节是字母(不是0..9或其他非字母),您可以跳过 IF 部分。

您可以无条件地设置或清除 Bit Nr,而不是20h用作 ASCII 中大写和小写之间的区别。5(ASCII 字符:第 7 位、...、第 0 位)。

通过将 ASCII 字符的第 5 位设置为 1,您会得到一个小写字母。通过将第 5 位设置为 0,您将获得大写字母。( http://asciitable.com/ )

获取大写。通过与设置了所有其他位的掩码进行与运算,将位 5 清除为 0 :

and al, 0xdf   ; you may use 0dfH instead of 0xdf in your notation, or ~0x20

获取小写字母。将位 5 设置为 1:

or al, 0x20    ; 20h

这对于检查字符是否为字母也很有用。您只需将所有字母设置为大写。之后,您使用“cmp”检查字符是低于“A”还是高于“Z”。如果不是,那就是一封信。甚至更好,

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
于 2014-12-29T01:09:13.730 回答
0

要有条件地进行转换,您通常会使用几个比较:

    cmp al, 'a'
    jl  not_lower
    cmp al 'z'
    jg  not_lower

    sub al, 20h

not_lower:

根据情况,还有另一种可能更可取:

    mov bl, al
    sub bl, 'a'
    cmp bl, 'z'-'a'   ; 25
    ja  not_lower

    sub al, 20h

not_lower:

让您只用一个 jmp 而不是两个,并有助于使其更可预测。

于 2012-10-13T00:57:19.590 回答