在程序集x86中查找字符串中的出现次数

jac*_*son 3 x86 assembly masm irvine32

我一直在研究这个程序,我必须输入一个字符串,然后在该字符串中显示字符分布.

例如:
如果输入是"minecode",则输出应为

C - 1
O - 1
D - 1
E - 2
I - 1
M - 1
N - 1

这是我试图做的,但我真的不知道如何遍历循环并检查相似的字符然后增加计数.汇编程序是在32位机器上运行的MASM 615.

.686
.MODEL flat, stdcall
.STACK
INCLUDE Irvine32.inc
.DATA
  msg0 BYTE "Enter a string of characters: ",0
  msg1 BYTE "Character Distribution: ",0
  MainArray    dword 10000 dup (?)
  UniqueChar   dword 10000 dup (?)
  CharCount    dword 10000 dup (?)
.CODE
MAIN PROC
    lea edx, msg0
    call WriteString
    call dumpregs        ; 1
    call ReadString
    mov MainArray, eax
    call dumpregs        ; 2
    mov MainArray, ebx
    call dumpregs        ; 3
    call CRLF
    lea edx, msg1
    call WriteString
    call CharDist        ; Calls the procedure
    call dumpregs        ; 5
    exit
MAIN ENDP
CharDist PROC
    mov ecx, lengthof MainArray
    mov esi, OFFSET MainArray
    L1:
; what to do here?? 
Loop L1:
CharDist ENDP
END MAIN
Run Code Online (Sandbox Code Playgroud)

Dav*_*lor 5

一种可能的方法:创建256个计数器的数组,将其基址存储在其中ebx,并且对于字符串中的每个字节,在该偏移量处递增计数器ebx.然后,循环遍历计数器阵列并打印非零计数.

你永远不会说这是一个以0字节(C风格)结尾的字符串,一个以其长度(Pascal风格)开头的字符串,或者是一个长度作为第二个参数传入的字符串,但这将决定何时终止循环.如果您正在寻找终止零,请测试您刚刚读取的字节,如果您正在计算特定数量的字节,请保留剩余的字节数ecx并进行测试.(ecx如果您不想使用它们,则有条件分支的特殊说明,如果您想使用它们.)

如果你把你的指针指向字符串中esi,你可以下一个字节加载到allodsb指令.或者,你可以mov[esi],然后inc esi.如果eax在存储每个字节之前将其清零al,这将为您提供一个索引eax,您可以使用一个计数器数组.

  • 但是,您建议使用LOOP指令来实现循环并不好.在大多数CPU上,[它太慢了,你可能会忘记它甚至存在](http://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-它有效),除非优化代码大小.我建议的另一件事是在循环中使用`movzx eax,byte [esi]`/`inc [table + eax]`.这可能比在循环外调零eax然后只修改循环内的低字节(例如使用LODSB)更容易.但两种方式都有效. (5认同)
  • 谁在赞同我们的评论?是否有人潜伏在我们的每一个字上? (2认同)