如何逐字符遍历字符串
How can I traverse a string character by character
我有一个 C 程序,它从标准输入接收一个字符串并将其传递给一个用 32 位 x86 汇编语言编写的函数,该函数必须执行以下操作:
- 检查字符串是否仅由字母数字字符组成。
- 如果上一个测试的答案是肯定的,那么return字符串原样
- 如果有一些非字母数字字符,函数必须用 spaces 删除它们。
- 检查完字符串中的每个字符后,函数必须 return 一个没有非字母数字字符的字符串。
这是该例程必须执行的操作的示例:
"only 4lph4numeric chars" INPUT
"only 4lph4numeric chars" OUTPUT
"here*some*for$bidden_chars#" INPUT
"here some for bidden chars" OUTPUT
我是汇编的新手,但我知道如何比较字符,我认为删除其中一个就足以用空白替换它 space。
真正的问题是我不知道如何逐个字符地遍历字符串;我读过一些关于 lods
的内容,但我不明白如何使用它。
你就是这样做的。下一个代码是使用 Visual Studio 2010 C++ 控制台项目制作的。首先是汇编部分,注意注释,如何从栈中获取字符串的地址,如何访问字符,最重要的部分,如何删除不需要的字符:
.386
.model flat, C
.code
;-------------------------------------------------------
check_alphanum proc
;PRESERVE EBP, ESI.
push ebp
push esi
mov ebp, esp
add ebp, 12 ;GET PARAMETER'S ADDRESS.
mov esi, [ ebp ] ;ESI POINTS TO ARRAY.
whil:
mov al, [ esi ] ;GET CURRENT CHAR.
cmp al, 0 ;CHECK END OF ARRAY.
je finale ;IF ( AL == 0 ) END OF STRING.
;CHECK IF CURRENT CHAR IS 0..9-A..Z-a..z.
cmp al, '0'
jb its_invalid ;IF ( AL < '0' ) INVALID.
cmp al, '9'
jbe its_valid ;IF ( AL <= '9' ) VALID.
cmp al, 'A'
jb its_invalid ;IF ( AL < 'A' ) INVALID.
cmp al, 'Z'
jbe its_valid ;IF ( AL <= 'Z' ) VALID.
cmp al, 'a'
jb its_invalid ;IF ( AL < 'a' ) INVALID.
cmp al, 'z'
jbe its_valid ;IF ( AL <= 'z' ) VALID.
jmp its_invalid ;INVALID BECAUSE AL > 'z'.
its_valid:
;NEXT CHAR TO PROCESS.
inc esi
jmp whil
its_invalid:
;DELETE CURRENT CHAR PUSHING ALL CHARS ONE PLACE TO THE LEFT.
mov edi, esi ;EDI POINTS TO CURRENT CHAR TO DELETE.
mov ebx, esi ;EBX ALSO POINTS TO CURRENT CHAR.
inc ebx ;NOW EBX POINTS TO NEXT CHAR.
shifting_left:
mov al, [ ebx ] ;AL = NEXT CHAR.
mov [ edi ], al ;CURRENT CHAR REPLACED BY NEXT.
cmp al, 0
je end_shifting
inc edi
inc ebx
jmp shifting_left
end_shifting:
jmp whil ;REPEAT PROCESS FOR NEXT CHAR.
finale:
;RESTORE EBP, ESI.
pop esi
pop ebp
ret
check_alphanum endp
;-------------------------------------------------------
end
现在是 C++ 部分。可以这样调用前面的过程,例如,从 "main" 方法:
extern "C" void check_alphanum ( char * arr );
...
char arr[] = "A213457B-3746DFA3-578EC20E-4567DFF2-08A1B3AC-7B125F3A";
check_alphanum( arr );
结果字符串是:
"A213457B3746DFA3578EC20E4567DFF208A1B3AC7B125F3A"
下图显示项目树中外部程序集文件的位置:
你所要做的就是向你的项目添加一个新文件,根据需要命名它,但使用“.asm”扩展名,将我的代码复制粘贴到其中,就这样,准备好使用(或准备打电话)。
我有一个 C 程序,它从标准输入接收一个字符串并将其传递给一个用 32 位 x86 汇编语言编写的函数,该函数必须执行以下操作:
- 检查字符串是否仅由字母数字字符组成。
- 如果上一个测试的答案是肯定的,那么return字符串原样
- 如果有一些非字母数字字符,函数必须用 spaces 删除它们。
- 检查完字符串中的每个字符后,函数必须 return 一个没有非字母数字字符的字符串。
这是该例程必须执行的操作的示例:
"only 4lph4numeric chars" INPUT
"only 4lph4numeric chars" OUTPUT
"here*some*for$bidden_chars#" INPUT
"here some for bidden chars" OUTPUT
我是汇编的新手,但我知道如何比较字符,我认为删除其中一个就足以用空白替换它 space。
真正的问题是我不知道如何逐个字符地遍历字符串;我读过一些关于 lods
的内容,但我不明白如何使用它。
你就是这样做的。下一个代码是使用 Visual Studio 2010 C++ 控制台项目制作的。首先是汇编部分,注意注释,如何从栈中获取字符串的地址,如何访问字符,最重要的部分,如何删除不需要的字符:
.386
.model flat, C
.code
;-------------------------------------------------------
check_alphanum proc
;PRESERVE EBP, ESI.
push ebp
push esi
mov ebp, esp
add ebp, 12 ;GET PARAMETER'S ADDRESS.
mov esi, [ ebp ] ;ESI POINTS TO ARRAY.
whil:
mov al, [ esi ] ;GET CURRENT CHAR.
cmp al, 0 ;CHECK END OF ARRAY.
je finale ;IF ( AL == 0 ) END OF STRING.
;CHECK IF CURRENT CHAR IS 0..9-A..Z-a..z.
cmp al, '0'
jb its_invalid ;IF ( AL < '0' ) INVALID.
cmp al, '9'
jbe its_valid ;IF ( AL <= '9' ) VALID.
cmp al, 'A'
jb its_invalid ;IF ( AL < 'A' ) INVALID.
cmp al, 'Z'
jbe its_valid ;IF ( AL <= 'Z' ) VALID.
cmp al, 'a'
jb its_invalid ;IF ( AL < 'a' ) INVALID.
cmp al, 'z'
jbe its_valid ;IF ( AL <= 'z' ) VALID.
jmp its_invalid ;INVALID BECAUSE AL > 'z'.
its_valid:
;NEXT CHAR TO PROCESS.
inc esi
jmp whil
its_invalid:
;DELETE CURRENT CHAR PUSHING ALL CHARS ONE PLACE TO THE LEFT.
mov edi, esi ;EDI POINTS TO CURRENT CHAR TO DELETE.
mov ebx, esi ;EBX ALSO POINTS TO CURRENT CHAR.
inc ebx ;NOW EBX POINTS TO NEXT CHAR.
shifting_left:
mov al, [ ebx ] ;AL = NEXT CHAR.
mov [ edi ], al ;CURRENT CHAR REPLACED BY NEXT.
cmp al, 0
je end_shifting
inc edi
inc ebx
jmp shifting_left
end_shifting:
jmp whil ;REPEAT PROCESS FOR NEXT CHAR.
finale:
;RESTORE EBP, ESI.
pop esi
pop ebp
ret
check_alphanum endp
;-------------------------------------------------------
end
现在是 C++ 部分。可以这样调用前面的过程,例如,从 "main" 方法:
extern "C" void check_alphanum ( char * arr );
...
char arr[] = "A213457B-3746DFA3-578EC20E-4567DFF2-08A1B3AC-7B125F3A";
check_alphanum( arr );
结果字符串是:
"A213457B3746DFA3578EC20E4567DFF208A1B3AC7B125F3A"
下图显示项目树中外部程序集文件的位置:
你所要做的就是向你的项目添加一个新文件,根据需要命名它,但使用“.asm”扩展名,将我的代码复制粘贴到其中,就这样,准备好使用(或准备打电话)。