如何计算字母字母出现在汇编语言的给定文本(字符串)中?

时间:2014-04-26 01:34:42

标签: assembly

我正在构建一个程序,该程序将计算给定文本中每个字母出现的字母数。例如,如果文本是" Hello World"那么输出就像:

H - 1次 e - 1次 l - 3次 o - 2次 W - 1次 r - 1次 d - 1次

问题是我们必须区分大小写。 我从谷歌获得了一个代码段,但我并不真正理解部分代码。我对代码进行了评论,我知道它的作用。有人可以向我解释一下吗?谢谢。

buffer  BYTE "AAbcd", 0
charInput   BYTE 26 DUP(0)    ; should the array size be greater than 26 ?
                              ; since we will need to counter the upper and lower ones



    CharCount PROC
    pushad

    XOR ebx, ebx
    XOR eax, eax
    XOR edx, edx
    mov esi, 0
    mov edi, 0
L1:
    mov al, buffer[esi]
    sub eax, 65 
    mov dl, charInput[edi + eax]    ; it stores the values at position [edi + eax] into dx ???
    inc dl                  ; 

    mov charInput[edi + eax], dl    ; what does it do in here ???
    inc esi             
    loop L1

    popad
    ret
CharCount ENDP


END main

2 个答案:

答案 0 :(得分:1)

让我们试一试。我也是在组装时生锈了。让我再评论一下。

buffer  BYTE "AAbcd", 0
charInput   BYTE 26 DUP(0)    ; should the array size be greater than 26 ? Yes - you may want to do 0-255 here
                          ; since we will need to counter the upper and lower ones



CharCount PROC
pushad                    ; push registers as backup

XOR ebx, ebx              ; shortcut to store 0 in ebx
XOR eax, eax              ; same for eax - your letter code will be here (A=0, Z=25)
XOR edx, edx              ; zero out edx. edx is your current register for storing the frequency
mov esi, 0                ; zero out esi - esi is the index to the letter being processed from the string
mov edi, 0                ; zero out edi as well - it doesn't seem like edi is ever non-zero here
L1:
mov al, buffer[esi]       ; grab the current letter to process and put into al (low part of eax)
sub eax, 65               ; substract 65 to shift ASCII A down to 0. You may wish to not shift this value and instead just use a larger array of 0-255.
mov dl, charInput[edi + eax]    ; grab the current frequency of the letter from charInput, the "histogram"
inc dl                  ; increment the frequency by one

mov charInput[edi + eax], dl    ; put it back into the histogram
inc esi                   ; move on to the next letter to proces
loop L1                   ; go back to the next letter

popad                     ; pop registers
ret
CharCount ENDP


END main

在此之后,您需要迭代扩展的charInput并转储出现次数。祝你好运!

答案 1 :(得分:1)

你要求的是解释而不是调试代码,这就是我要提供的内容。

在你要求的评论中

  

如果数组大小应该大于26?

如果通过“区分大写和小写”来表示您想要将a的数量与A的数量分开计算,那么您需要将数组保持为52条目,还需要范围检查输入字符。数字65是ASCII大写A,ASCII中的小写a是97(32多),但在代码中使用字符常量将有助于使其更具可读性。

这很容易。

您要求的行

  

它在这里做了什么???

正在索引到你正在进行计数的数组中:获得数字并递增它然后将值返回。正如@ J-trana所说,edi看起来并不像以前那样:我的猜测是它的目的是使大写/小写区分更容易,并且如果字符是小写(通过ANDing buffer[esi]与32)。结果是数组不应该是52而是64字节长。

同样,J-trana正确地建议使数组足够大以容纳每个可能的值,所以256字节。这样可以简化索引,几乎可以肯定无需使用edi

那是你问过的那个。

当然有“陷阱”,即LOOP依赖于cx,但没有任何设定。这样做的简单方法是将其计算为charInput - 就在L1之前的缓冲区。