制作频率表

时间:2013-12-05 05:20:45

标签: assembly x86 masm irvine32

我应该创建一个包含256个DWORD的频率表,并使用ASCII代码作为索引来计算字符串中字符的出现次数。我陷入了如何使用存储的ASCII值作为索引并增加该索引的问题。这是我到目前为止所拥有的。

    TITLE String Find

    INCLUDE Irvine32.inc
    Get_freqs PROTO, 
        ptrTarget:PTR BYTE, 
        ptrFreqTable:PTR BYTE

    .data
    targetStr BYTE "AAEBDCFBBC",0
    freqTable DWORD 256 DUP(0)
    .code

    main PROC

    INVOKE Get_freqs,  ADDR targetStr, ADDR freqTable
    mov ecx,LENGTHOF freqTable
    mov edx,LENGTHOF freqTable
    L1:
        push    edx
        mov eax,edx
        call    writeInt
        mov al,' '
        call writeChar
        mov eax,OFFSET freqTable
        add eax,ecx
        call writeInt
        pop edx
        dec edx
        loop L1

    exit
    main ENDP

    Get_freqs PROC, 
        ptrTarget:PTR BYTE,
        ptrFreqTable:PTR BYTE

    INVOKE Str_length,ptrTarget         ; EAX = length source
    mov ecx,eax
L1:
    mov eax,ptrTarget[ecx]
    add eax,ptrFreqTable
    loop L1
    ret

    Get_freqs   ENDP 

    END main

这是我遇到麻烦的部分。

L1:
    mov eax,ptrTarget[ecx]
    add ptrFreqTable[eax],1
    loop L1

2 个答案:

答案 0 :(得分:2)

您只想从字符串中读取字节,然后缩放它们以访问DWORD数组。所以替换:

L1:
    mov eax,ptrTarget[ecx]
    add ptrFreqTable[eax],1
    loop L1

有类似的东西:

L1:
    movzx eax, byte ptr ptrTarget[ecx - 1]
    add ptrFreqTable[eax*4 - 4],1
    loop L1

-1-4是因为您实际上是从length(string)循环到1(LOOP递减CX并在CX时停止循环等于0)。

答案 1 :(得分:0)

我通过使用一些我在发布时没有教过的指令来修复它。

L1:mov eax,0                    ; clear upper bits of EAX
    lodsb                       ; AL = [ESI], inc ESI
    cmp al,0                    ; end of string?
    je done                     ; yes: exit
    shl eax,2                   ; multiply by 4
    inc DWORD PTR[edi+eax]      ; add to table entry
    jmp L1
done:

我的显示技术也存在缺陷,但由于这不是我的问题的一部分,我会留在这里,这样当我回到这里时,我可能会在额头上拍打自己。