Search code examples
assemblytasmdosbox

assembly code to find the max number of consecutive ones


How can I find the max number of consecutive ones in a byte when I took a character from user and determine the number of max consecutive ones in the byte. I tried this code but it is not working, it is print all ones in the number not the consecutive ones.

.model small
.stack  100
.data
    message db "Enter one charachter $" 
    NewLine DB 0DH,0AH, "$"
    message db "Enter one charachter $" 
    NewLine DB 0DH,0AH, "$"
    message2 db "The maximum number of consecutive ones is $" 

.code
    mov ax, @data
    mov ds,ax
    push ax
    mov ah,09 
    lea dx,message 
    int 21h 
    pop ax
    MOV AH,09 
    MOV DX,OFFSET NewLine 
    INT 21H 
    mov ah,1
    int 21h
    mov si,0
    mov di,8
    l1:
        shl al,1
        jnc no_inc_count
            inc si
        no_inc_count:
        dec di
    jnz l1
    MOV AH,09h
    MOV DX,OFFSET NewLine 
    INT 21H 
    push ax
    mov ah,09 
    lea dx,message2 
    int 21h 
    pop ax
    MOV AH,09 
    MOV DX,OFFSET NewLine
    INT 21H 
    mov ah,2
    add si,30h
    mov dx,si
    int 21h
    mov ah,4ch 
    int 21h 
end

Solution

  • his block counts all ones:

    mov si,0
    mov di,8
    l1:
    shl al,1
    jnc no_inc_count
    inc si
    no_inc_count:
    dec di
    jnz l1
    

    SI is the "one"-counter which counts the ones.
    DI is the "loop"-counter which counts (down) the shifts.

    If want to store the maximum number of ones you need to add a variable "max" and two pieces of code:

    • Code which resets the one-counter if the fetched bit is null.
    • Code which compares the maximum with the one-counter and replace it eventually.

    I hope the comments in the following code make it little bit clearer:

    .MODEL small
    .STACK                          ;  Default 1024
    
    .DATA
    message     db "Enter one character $"
    message2    db "The maximum number of consecutive ones is $"
    NewLine     db 0DH,0AH, "$"
    max         dw 0            ; Holds the maximum number of consecutive ones
    
    .CODE
    start:                      ; Entry point needed for END
        mov ax, @data           ; Let DS point to .DATA
        mov ds,ax
    
        mov ah,09h              ; http://www.ctyme.com/intr/rb-2562.htm
        lea dx,message
        int 21h                 ; Call MS-DOS
    
        mov ah, 01h             ; http://www.ctyme.com/intr/rb-2552.htm
        int 21h                 ; Call MS-DOS
    
        mov si, 0               ; One-counter
        mov di, 8               ; Loop-counter: Shift 8 bits
    
        FOR:                    ; Loop 8 times
        shl al, 1               ; shift one bit into carry flag (CF)
        jnc IS_NULL             ; jump if no "one"
    
        IS_ONE:                 ; Code to increment one-counter and replace max
        inc si                  ; one-counter++
        cmp si, max             ; si > max ?
        jbe LOWER               ; No - comparation has set CF or ZF
            GREATER:            ; Yes, si > max (comparation has cleared CF and ZF)
            mov max, si         ; Replace max by SI
            LOWER:
        jmp CONTFOR             ; Decrement loop-counter and loop
    
        IS_NULL:
            mov si, 0           ; Reset one-counter
    
        CONTFOR:                ; Decrement loop-counter and continue looping
        dec di
        jnz FOR
    
        mov ah, 09h             ; http://www.ctyme.com/intr/rb-2562.htm
        lea dx, NewLine
        int 21h                 ; Call MS-DOS
    
        mov ah, 09h             ; http://www.ctyme.com/intr/rb-2562.htm
        lea dx, message2
        int 21h                 ; Call MS-DOS
    
        add max, 30h            ; To ASCII
        mov ah, 2               ; http://www.ctyme.com/intr/rb-2554.htm
        mov dx, max
        int 21h                 ; Call MS-DOS
    
        mov ah, 09h             ; http://www.ctyme.com/intr/rb-2562.htm
        lea dx, NewLine
        int 21h                 ; Call MS-DOS
    
        mov ax,4C00h            ; AH=4Ch (exit), exitcode AL=0 (ok)
        int 21h                 ; Call MS-DOS
    
    END start                   ; END < entry point >
    

    Notes:

    • The program needs an entry point (label) which doesn't need to be at the beginning of the code. That entry point is the argument of the END statement.
    • Don't use PUSH and POP when you don't know exactly what you're doing. Use variables in the .DATA segment instead.
    • It doesn't matter, if you use capital letters (MOV AH,09h) or small letters (mov ah,09) characters, but you should keep to the method of your choice.
    • Find a style for formatting your code e.g. with indenting and new lines, so that you can still understand it after a few days. Comments serve the same purpose.