The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ch4o7ic on October 13, 2005, 11:03:24 PM

Title: frequency table
Post by: ch4o7ic on October 13, 2005, 11:03:24 PM
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
Title: Re: frequency table
Post by: raymond on October 14, 2005, 02:49:27 AM
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
Title: Re: frequency table
Post by: ch4o7ic on October 14, 2005, 03:03:48 AM
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..
Title: Re: frequency table
Post by: Farabi on October 15, 2005, 02:26:43 AM
use lstrlen on the latest MASM package. BUt as long as your text string is terminated with zero.