News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

frequency table

Started by ch4o7ic, October 13, 2005, 11:03:24 PM

Previous topic - Next topic

ch4o7ic

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

raymond

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
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ch4o7ic

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..

Farabi

use lstrlen on the latest MASM package. BUt as long as your text string is terminated with zero.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"