; multi-segment executable file template.

data segment
string db "THis is LuxUR in Summer."

stack segment
dw 128 dup(0)

code segment
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax

mov bx, offset string
mov al, 0 ; lower letters in word
mov dl,0 ; maximum letters

mov cl, 41h ; from A-Z
mov ch, 5Ah

mov ah, [bx]
cmp ah, "."
je dot
cmp ah, " "
je empty
jne letters

cmp ah, cl
je uppercase
inc cl
cmp cl, ch
jne letters

mov cl, 61h ; a-z
mov ch, 7Ah

inc al
cmp dl,al
jl maksimum

inc bx
jmp check

mov dl, al

inc bx
jmp check

inc bx
jmp check

mov al, 0
inc bx
jmp check


My program count lowercases in a word in al. and then puts in dl. (maximum lowercases) I have label which name is dot. there I have to put some instruction by which I can print my result:

Summer is the word with the most lower cases 5

I try few instructions to do that but it doesnt work.

I'm not sure exactly what you're up to, and I won't write finished code, but here are a few suggestions. First, you need to know if your code is in a 16, 32, or 64 bit segment. I will assume a 32 bit segment, in which case all registers and operands will default to 32 bits. For bulletproof code, I would recommend using operand size prefixes where appropriate. Now, since you're setting ES anyway, use one of the string instructions, in this case, LODSB. And use the LOOPNZ instruction for loop control (ECX as a counter). Here's an untested bit to count capitals and lowercase:

Push ESI    //You really should save these so you can restore them later
   Push ES
   Push DS
   ...        //Your code to set the new values in the segment regs
   ...        //And define the character string - make sure it's null terminated!

   mov esi, Offset string //DS:ESI must point to string for lodsb.
// (ES:DSI & DS:ESI are used for movsb, which you may need later)

//Stringlength is optional. You could use scansb to find it, or just set it to
//a value you know is larger than the string and stop the loop on a null character
//with loopnz (see below). If this is 16 bit segment, use CX instead, ditto for SI.

   mov ecx, StringLength //You could use scansb to find this or just set it large

   lodsb       //Put next character in AL
   mov ah, al  //Make copy of character in AH
   and ah, 0xDF //Remove bit that distinguishes between lower and upper case
   cmp ah, 0x41 //Test for lower and upper case A
   jb Loopy  //Not a letter, loop on next character
   cmp ah, 0x5A //Test for lower and upper Z
   ja Loopy  //Not a letter, loop on next character
   bt ax,5      //Test the 0x20 bit in AL
   jc isLowerCase //if set, it's lower case
   inc UpperCaseCount //Count upper case characters
   jmp Loopy          //and loop
   inc UpperCaseCount //Count lower case characters and loop
   cmp al,0           //set zero flag if null terminator
   loopnz NextChar    //loop till count or null terminator

...Any additional code you need

   pop ESI    //restore them
   pop ES
   pop DS

Loop exits with counts set, either when the string length is reached or a
null byte is found. Strategy depends upon the fact that A-Z is 0x41-0x5A and
a-z is 0x61-0x7A, that is, if the 0x20 bit is set and in the a-z range, its lower case. That's why I test range on AH with the 0x20 bit removed (with the AND 0xDF),
which makes the upper and lower case range the same. Then test the still unchanged
AL to see if the lower case bit is set. This snippet probably has some bugs and I
intentionally left out segment stuff and definitions of the counters, etc. Remember also to POP anything else off the stack that you've saved there. Finally, why are you messing with the stack segment at all? I would just use the stack segment that the OS provides when it enters your code unless you plan to do some really massive stuff with the stack - but then, you've only defined a tiny stack segment. Good luck!

This article has been dead for over six months. Start a new discussion instead.