使用 scasb 统计某个单词在句子中出现的次数

问题描述 投票:0回答:1

我一直在做一些使用 masm 的练习任务,我想出了如何用一些字符(在本例中为空格)替换句子的一部分。但我一生都无法弄清楚如何应用同样的逻辑来简单地计算单词出现的次数。

这是我想到的例子

.386
.model flat, stdcall
option casemap:none

include \masm32\include\kernel32.inc     
include \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
                     
.stack 4096

.const
Space equ ' '
Punkts equ '.'

.data
buffer byte ' Test  test tes t  ', 0 
BufLen equ $ - buffer - 1


.code
start proc            
     push es
            push ds
            pop es
            xor bx, bx
            cld                   
      mov ecx, BufLen
            mov al, Space           
     lea edi, buffer
Next:
            repne scasb            
            jne No           
            mov es:[edi - 1], byte ptr Punkts
 
            inc bx
     cmp cx, 0
            jne Next
No:
            invoke StdOut, addr buffer
            pop es            
            push 0
            call ExitProcess 
start endp
        end start

如有任何帮助,我们将不胜感激

assembly x86 masm
1个回答
0
投票

清理

使用 32 位寄存器,不用关心 Windows 程序中 DS 和 ES 段寄存器中的内容(

kernel32.inc
kernel32.lib
call ExitProcess
)。

.386
.model flat, stdcall
option casemap:none

include \masm32\include\kernel32.inc     
include \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
                     
.stack 4096

.const
Space  equ ' '
Punkts equ '.'

.data
buffer byte ' Test  test tes t  ', 0 
BufLen equ $ - buffer - 1

.code
start proc
      mov  al, Space
      xor  ebx, ebx                   ; Count of replacements
      mov  ecx, BufLen
      mov  edi, addr buffer
Next: repne scasb
      jne  No
      mov  byte ptr [edi - 1], Punkts
      inc  ebx                        ; Increment the counter
      test ecx, ecx
      jnz  Next
No:   invoke StdOut, addr buffer
      push 0
      call ExitProcess
start endp
end start

计算 1 个字符单词的出现次数

与上面相同的代码,但删除了显然不需要的

mov  byte ptr [edi - 1], Punkts
之后。

计算多字符单词的出现次数

像以前一样,我们查找单词的第一个字符,如果找到它,我们将启动一个嵌入循环(“内循环”)来查找剩余的字符。让内循环不要修改ECX和EDI寄存器!
如果这个内部循环遇到不匹配,那么你就像以前一样继续外部循环。
如果此内部循环除了匹配之外什么都没有完成,那么您将递增计数器,并将 EDI 提高 WordLen-1 并降低 ECX WordLen-1。

.data
TheWord byte 'Tom', 0
WordLen equ  $ - TheWord - 1
buffer  byte 'Tomorrow we meet Tom.', 0
BufLen  equ  $ - buffer - 1

...

      xor  ebx, ebx                   ; Count of occurences
      mov  ecx, BufLen
      mov  edi, addr buffer
OuterLoop:
      mov  al, TheWord                ; First character is 'T'
      repne scasb
      jne  No

InnerLoop:     ; Compare the 2nd char of the word with [edi] and so on

      ...

Match:
      inc  ebx                        ; Increment the counter
      add  edi, WordLen-1
      sub  ecx, WordLen-1
MisMatch:
      test ecx, ecx
      jnz  OuterLoop
No:
      invoke StdOut, addr buffer
      push 0
      call ExitProcess
© www.soinside.com 2019 - 2024. All rights reserved.