带有ascii索引和十进制值的频率表

时间:2013-05-09 20:55:34

标签: assembly x86 masm irvine32

我将代码写入计算机中每个字符的频率,而数组的索引是0到255,它们是ascii索引,值是字符出现的频率。

我比较字符串中的每个字符,每次在数组中将它加1。

但我找不到计数似乎不正确(太大)的错误?

结果应为enter image description here

但我的结果数太大了。

错误出现在L1循环中,我不知道为什么循环会导致非常大的数字。

请给我一些指导,说明我做错了。

感谢您的阅读。

INCLUDE Irvine32.inc

.data
    testString BYTE "AAEBDCFBBC",0 
    freqTable DWORD 256 DUP(0)
    prompt BYTE 0Dh, 0Ah, 0
    prompt1 BYTE ": ", 0
.code   


Freq PROC uses edi,
        tString:PTR BYTE, 
        fTable:PTR DWORD

    mov eax,0
    CLD

    mov edi,fTable  
    mov ecx,256
    rep stosd;initialize fTable 0


    mov edi,fTable;reset edi position
    mov edx,tString
    mov ecx,SIZEOF tString;element number
    dec ecx;remove null character

    L1:
    mov al,[edx]  ;character value
    inc edx     ;index ++
    inc dword ptr[edi+eax] ;value ++
        Loop L1
    ret
Freq ENDP


main PROC
main ENDP
    INVOKE Freq, ADDR testString, ADDR freqTable
    mov ecx, 256
    mov ebx, 0
    mov edi,OFFSET freqTable
    mov eax, 0

    L1:
        call WriteHex;index
        mov  edx,OFFSET prompt1
        call WriteString;": "

        mov ebx, [edi + eax]
        xchg eax,ebx
        call WriteInt
        xchg eax,ebx
        mov  edx,OFFSET prompt
        call WriteString;endline
        inc eax;index ++
        Loop L1
        ;ret
END main

1 个答案:

答案 0 :(得分:1)

乍一看,您的代码似乎正确。我发现行mov ecx,SIZEOF tString有点可疑,请确保返回字符串的大小 - 我担心它只返回指针的大小。 (但这应该使计数减少不多。)

此外,在写循环期间,请确保您调用的各种函数不会更改您依赖的任何寄存器,尤其是eax存在危险。

否则,您应该使用调试器来检查生成的结果是否正确,这样您就可以判断它是Freq函数还是打印循环错误。找到后,你应该逐步查看它出错的地方。

<强>更新

您的freqTable显然由dwords(每个4个字节)组成,但您的索引使用1个字节的单位。您必须在计数循环中将inc dword ptr[edi+eax]更改为inc dword ptr[edi+eax*4],并在打印循环中将mov ebx, [edi + eax]更改为mov ebx, [edi + eax*4]