hi  :),
i'm trying to write an assembly code to find the character that the maximum occurence in a string but i have some problems.can anybody help me please :sad:
here is my code
model small
.stack 100h
.data
chaine db "i want to test$"
char db '$'
nr dw ?
tch dw ?
entre dw 10,13,'$'
msg4 dw "the character with a maximum occurence is:$" 
.code
mov tch,14
mov si,offset chaine
mov nr,0
mov cx,tch
dec cx
mov dx,si
add dx,tch
repete14:
mov bx,0
mov al,
mov char,al 
repete24:
mov al,
cmp al,char
je meme
jmp different
meme:
inc bx
different:
inc al
cmp al,dx
jg repete24
inc si
cmp dx,nr
jg affecter
loop repete14
affecter:
mov nr,bx
loop repete14
mov dx,offset msg4
mov ah,9
int 21h
mov ax,nr
mov ah,2
int 21h
mov dx,offset entre
mov ah,9
int 21h
Posted on 2010-11-23 16:43:17 by marooh
Well, I'm Nasmist, and we do things slightly different than Masm. I'm not sure exactly what you're trying to do here. Some comments might help - help others reading your code, and maybe help you, too! I can still make some suggestions...


chaine db "i want to test$"


You've got a $-terminated string. Good for printing with int 21h/9, but outside of int 21h/9, '$' is a perfectly legitimate character to appear in a string. You might want to use a zero-terminated string instead. It is possible to do both. You don't currently print this string, but you might want to - just to let the user know what string we're working with...


entre dw 10,13,'$'
msg4 dw "the character with a maximum occurence is:$" 


13, 10 is "canonical", not 10, 13. Probably won't hurt. Both of these should be "db", not "dw".


.code
mov tch,14  ; length of string?
mov si,offset chaine
...


You don't seem to indicate an entrypoint here (unless the "simplified segment directive" does it - I don't think so). AIUI, Masm indicates that "foo:" is the entrypoint with "end foo" at the end of the code. If this is going to be a .com file, that isn't necessary, but I think "model small" indicates an .exe. If so, you also need to initialize ds!!!


mov ax, @data
mov ds, ax



...
mov al,


Unless you're looking for double characters, I'm not sure what this is going to do...


different:
inc al
cmp al,dx


This is just plain wrong. I don't think it'll even assemble - you can't compare an 8-bit register to a 16-bit register! Maybe you intended si here, not al?

You seem to be looping over the string several times. Perhaps you can get that to work, but I'd take a slightly different approach. I'd walk down the string just once, and keep track of the "count" in an array of character counts. Ummm...


char_counts 256 dup dw 0


(not sure of the syntax for "dup") Some "wasted" space there, but I think it'll simplify(?) the code a little. Then, as I get each character, I'd convert it into an index into the array, and increment the count for that character...


next_char:
mov al,   ; get a character
inc si  ; get ready for the next one (also see "lodsb")

; have we reached the end of the string?
cmp al, '$'  ; or preferably(?) zero
jz finished

; now convert the character into an index into the array
mov bl, al
mov bh, 0  ; make sure upper bits of bx are clear
add bx, bx  ; or otherwise double it - we have a word (16-bit) array!
mov cx,
inc cx
mov , cx
; could have just "inc word ptr ", but...

; see if it's our new champion
cmp , cx
jb skip ; if not, do nothing

; update the scoreboard
mov , cx
mov , al

skip:
jmp next_char

finished:
; print the result
; don't forget to exit back to dos!


I don't know if that idea will help you or not, but I don't see how it's going to work the way you're trying to do it. Courage! :)

Best,
Frank

Posted on 2010-11-25 21:27:28 by fbkotler