繁体   English   中英

将小写转换为大写汇编

[英]Converting lowercase to uppercase assembly

所以我有一个将两位十六进制数转换为十进制数的程序。 我需要这样做,以便您可以输入 0...9 和字母 a...f 和 A...F 中的数字,因为现在它使用“SUB DL,32H”行将小写字母转换为大写,但它也会改变大写字母的值。 如何修复它并将输入限制为仅 a...f、A...F 和 0...9?

#MAKE_EXE#

DSEG    SEGMENT 'DATA'  

MSG DB 'Enter a two-digit hexadecimal number: $'

DSEG    ENDS

SSEG    SEGMENT STACK   'STACK'
    DW      100h    DUP(?)  
SSEG    ENDS

CSEG    SEGMENT 'CODE'  

;*******************************************

START   PROC    FAR 

PUSH    DS
MOV     AX, 0
PUSH    AX

MOV     AX, DSEG
MOV     DS, AX  

MOV AH,09h      
MOV DX, OFFSET MSG
INT 21h
XOR AX,AX       
MOV AH,1H       
INT 21H 
MOV DL,AL   
SUB DL,30H  
CMP DL,9H   
JLE M1  
SUB DL,7H   
SUB DL,32H
M1:     
MOV CL,4H   
SHL DL,CL   
INT 21H 
SUB AL,30H  
CMP AL,9H   
JLE M2  
SUB AL,7H   
M2:     
ADD DL,AL   

        
RET     
 
START   ENDP    

;*******************************************

CSEG    ENDS    

    END    START  

至于现在它将小写字母转换为大写字母“SUB DL,32H”

这不是这条指令所做的,从小写到大写的转换必须减去 32 小数。 与 20h 十六进制相同。

如何修复它并将输入限制为仅 a...f、A...F 和 0...9?

了解这些字符的 ASCII 码是什么很重要。 它将允许我们编写一个几乎没有比较的高效代码。

char   ASCII
0..9   30h..39h
A..Z   41h..5Ah
a..z   61h..7Ah

下一个代码验证用户输入并在AL中传递一个 0..15 范围内的值。 由于您的程序需要此过程两次,因此您应该将此代码放在主代码call两次的子例程中。

GetChar:
 mov  ah, 01h       
 int  21h
 sub  al, 30h
 cmp  al, 9
 jbe  M1               ; It was a digit 0..9

 sub  al, 41h - 30h    ; -30h because that has already been subtracted!
 cmp  al, 5
 jbe  M2               ; It was an uppercase A..F

 sub  al, 61h - 41h    ; -41h because that has already been subtracted!
 cmp  al, 5
 ja   GetChar          ; It's not lowercase a..f, invalid hexdigit, redo

M2:
 add  al, 10           ; 0..5 + 10 -> 10..15
M1:

请注意,我使用了未签名的jbe而不是签名的jle

 CMP DL,9H JLE M1

ASCII 码范围为 0..255。 如果您在这里使用带符号的jle ,那么额外的 128 个字符将被视为数字!


更短的代码

仍在验证用户输入,但特别是删除第三个分支可以使其更快。

GetChar:
 mov  ah, 01h       
 int  21h
 sub  al, 30h
 cmp  al, 9
 jbe  M1               ; It was a digit 0..9

 or   al, 20h          ; Case insensitiveness
 sub  al, 61h - 30h    ; -30h because that has already been subtracted!
 cmp  al, 5
 ja   GetChar          ; It's not A..F a..f, invalid hexdigit, redo
 add  al, 10           ; 0..5 + 10 -> 10..15

M1:

最短代码

仅当您相信键盘上的用户将始终输入有效的十六进制数字时。 不太现实!

GetChar:
 mov  ah, 01h       
 int  21h
 sub  al, 30h
 cmp  al, 9
 jbe  M1               ; It was a digit 0..9

 and  al, 15
 add  al, 9            ; 1..6 + 9 -> 10..15

M1:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM