【发布时间】:2016-11-01 18:11:13
【问题描述】:
我正在写将预设字符串从大写转换为小写。我目前正在将地址中的内容移动到一个 8 位寄存器,然后以一种非常草率的方式测试 ASCII 值以查看它是否为大写。有没有更清洁的方法?
现在我从 ASCII 值中减去 65 并与 25 进行比较。由于大写字母是 ASCII(十进制)65-90,因此任何大写字母都会产生 0-25。
.DATA
string DB "ATest This String?.,/[}", '$'
strSize DD 23
.CODE
strToLower PROC
LEA EAX, string
PUSH EAX
CALL toLower2 ; write toLower2
POP EAX
LEA EAX, string ; return char* to C++
RET
strToLower ENDP
;---------------------------------------------
;Procedure: Convert to LowerCase
;Input: Address in EBX
; unsigned in AL for each letter
;Output: EAX will contain new string
;---------------------------------------------
toLower2 PROC ;65-90 is upper, 97-122 is lower (XOR 32?)
LEA EBX, string
MOVE ECX, strSize
PUSH AL ; PUSH AL before manipulating it
loop1: MOV AL, [EBX] ; Put char into AL to manipulate
XOR BL, BL ;?????????????
MOV BL, AL ;Set condition here???
SUB BL, 65 ;?????????????
CMP BL, 25 ;if(i > 64 && < 91) i += 32;
JA NoCap ;
ADD AL, 32 ;Adds 32 to ASCII value, making lower
NoCap: MOV [EBX], AL
INC EBX
LOOP loop1
POP AL ;Replace/POP AL
LEA EAX, string
toLower2 ENDP
END
【问题讨论】:
-
将
0x20添加到字符中。如果0x61 <= char <= 0x7a,则存储。否则移动到下一个字符 -
这段代码无效,它会在第一个字符后覆盖其他一些内存。您是否在调试器中检查过它,它在做什么?有“??????”
xor bl,bl之后的评论看起来并不乐观。您还可以使用sub bl,'A'而不是“sub bl,65”(或更改编译器,如果它不适用于字符文字)......所以在添加 0x20 后,您可以测试“如果低于'a'跳过写入”和“如果高于'z'跳过写入”否则“将新值写回字符串”。无需将这些 ASCII 字符作为数字写入源代码。 -
@Ped7g:用一个分支检查范围的两侧(使用 sub/cmp/unsigned-jcc),实际上是一种很好的技术,并且效果很好。
-
@PeterCordes:是的,这不是我评论的重点,我什至建议他如何重写
sub以使其更具可读性。尽管 OP 代码的其他问题表明他最好坚持简单的“英语”流控制,并进行双方范围测试。我永远不知道如何回答那些认为bl和ebx是独立寄存器的人——除非在我的每个答案中写下几乎完整的教程。因此,我通常只是在评论中询问一些内容,然后等待 OP 是否进行了足够的沟通(值得付出努力,并集中精力)。但是 OP 在“第 0 课”ATM 上。
标签: assembly x86 masm lowercase