[英]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.