i am making a frequency table (of dwords) to see how offten each character is used in a given source string. everything works just fine, except for one thing, when i make a call to dumpmem to check the contents of the table, everything has been returned as bytes instead of dwords, so all the numbers are correct, but in the wrong places. can anyone help me?
thanks in advance...
here is the procedure...
TITLE Get Frequencies (_GetFrequencies.asm)
Include String.inc
.code
;-----------------------------------------------------
Get_frequencies proc,
ptrString:ptr byte,
ptrTable:ptr dword
;
; This procedure constructs a character frequency
; table. Input parameters are a pointer to a string
; and a pointer to an array of 256 DWORD's. Each
; array position is indexed by its corresponding ASCII
; code. When the procedure returns, each entry in the
; array cointains a count of how many times that
; character occured in the string.
; Returns: nothing
;-----------------------------------------------------
pushad ; push registers
mov esi, ptrString ; esi = source
mov ebx, ptrTable ; ebx = the table
mov eax, 0 ; eax = 0
cld ; set direction, left to right
aLoop:
lodsb ; al = character
movzx eax, al ; move al to eax
mov edi, [ ebx + eax ] ; edi = location of letter at table
inc edi ; increment value
mov [ ebx + eax ], edi ; store new value back in table
loop aLoop ; loop block
popad ; pop registers
ret
Get_frequencies endp
end
and here is the test program...
TITLE String Tester (StringTester.asm)
; Nick Hauschild
; Csci 373
; Homework 9
; This program is used to test the two procedures
; that were assigned for homework 9. The names
; of the procedures are Get_frequencies, and
; Str_nextword.
Include String.inc
.data
freqTable DWORD 256 dup(0)
testString BYTE "abcdefg", 0
char BYTE ','
.code
main proc
mov edx, offset testString
call writeString
call crlf
mov ecx, lengthof testString
invoke Str_nextword,
ADDR testString,
char
mov edx, offset testString
call writeString
call crlf
mov edx, eax
call writeString
mov ecx, lengthof testString
invoke Get_frequencies,
addr testString,
addr freqTable
mov esi, offset freqTable
mov ecx, lengthof freqTable
mov ebx, type freqTable
call dumpmem
exit
main endp
end main
Your characters range from 0-255 only. Your have to multiply the character by 4 to point to the proper place in your table of dwords. I don't know either how your loop instruction can work without setting a count in the ECX register. Try this if your string is null-terminated:
pushad ; push registers
mov esi, ptrString ; esi = source
mov ebx, ptrTable ; ebx = the table
xor eax,eax ;instead of: mov eax, 0 ; eax = 0
; not necessary: cld ; set direction, left to right
aLoop:
lodsb ; al = character
test al,al ;check if end of string
jnz @F
popad ; pop registers
ret
@@:
;not necessary, the remainder of EAX already zeroed: movzx eax, al ; move al to eax
inc dword ptr[ebx+eax*4]
;mov edi, [ ebx + eax ] ; edi = location of letter at table
;inc edi ; increment value
;mov [ ebx + eax ], edi ; store new value back in table
jmp aLoop ; loop block
Get_frequencies endp
end
Raymond
thank you so much raymond, you were absolutely correct, all i had to do was multiply eax by 4 at the memory location.
again, thanks alot!!!
by the way, my test program set ecx for the loop...i didnt know how to get the lenght of my source string from an address in the procedure..
use lstrlen on the latest MASM package. BUt as long as your text string is terminated with zero.