如何逐个字符遍历字符串

时间:2015-05-19 13:00:31

标签: c string assembly x86

我有一个C程序从标准输入接收一个字符串并将其传递给用32位x86汇编编写的函数,该函数必须执行以下操作:

  • 检查字符串是否仅由字母数字字符组成。
  • 如果上一个测试的答案为是,则返回字符串
  • 如果有一些非字母数字字符,则该函数必须用空格删除它们。
  • 一旦检查了字符串中的每个字符,该函数必须返回一个没有非字母数字字符的字符串。

这是例程必须做的一个例子:

"only 4lph4numeric chars"        INPUT
"only 4lph4numeric chars"        OUTPUT

"here*some*for$bidden_chars#"    INPUT
"here some for bidden chars"     OUTPUT

我是汇编的新手,但我知道如何比较角色,我认为删除其中一个足以用空格代替它。

真正的问题是我不知道如何逐字遍历字符串;我读过有关lods的内容,但我不明白如何使用它。

1 个答案:

答案 0 :(得分:1)

这是你如何做到的。下一代码是使用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 ++部分。可以像这样调用先前的过程,例如,来自&#34; main&#34;方法:

extern "C" void check_alphanum ( char * arr );
...
char arr[] = "A213457B-3746DFA3-578EC20E-4567DFF2-08A1B3AC-7B125F3A";
check_alphanum( arr );

结果字符串是:

"A213457B3746DFA3578EC20E4567DFF208A1B3AC7B125F3A"

下一个图像显示项目树中外部装配文件的位置:

enter image description here

您所要做的就是在项目中添加一个新文件,根据需要命名,但使用&#34; .asm&#34;扩展程序,将我的代码复制粘贴到其中,并准备好使用(或准备调用)。