Search code examples
assemblynasmdos16-bit

Assembly program to add odd numbers using conditional jump


I have a assignment:

Write an Assembly code to add following fifteen odd numbers with using conditional jump.

Odd numbers: 3, 5, 7, 9, 11, 13, 15, 17, 19, 21,23,25,27,29,31

I make this solution. I want to check this whats wrong in it...

[org 0x0100]
mov bx, num1
mov cx, 15
mov ax, 0
li:
add ax, [bx]
add bx, 2
sub cx, 1
jnz li
mov ax, 0x4c00
int 0x21
num1: dw 3, 5, 7, 9, 11, 13, 15, 17, 19, 21,23,25,27,29,31

Solution

  • That's certainly one way to do it, the only thing you need to be careful of is the fact you're accumulating the sum in ax but then you overwrite ax when you exit the program with int 21, fn 4c.

    By a happy coincidence, those numbers sum to 255 so it will actually fit into al, which is the register used for the return code by that interrupt (see Ralf Brown's excellent interrupt list).

    Whether DOS will do anything intelligent with it, I couldn't say :-)

    In order to preserve al when you exit the program, simply do this instead:

    mov  ah, 0x4c
    int  0x21
    

    The other thing you may want to consider doing is to print the item directly rather than returning it. The following code shows how to do this, using a function from my arsenal, capable of outputting the al register as a base-ten value:

            org     00100h
    
            mov     bx, num1
            mov     cx, 15
            mov     ax, 0
    li:
            add     ax, [bx]
            add     bx, 2
            sub     cx, 1
            jnz     li
    
            call    prt_byte
    
            mov     ah, 04ch
            int     021h
    
    num1:   dw      3, 5, 7, 9, 11, 13, 15, 17, 19, 21,23,25,27,29,31
    eoln:   db      0dh, 0ah, '$'
    
    prt_byte:
            push    ax
            push    bx
            push    dx
    
            cmp     ax, 100
            jl      skip_h
    
            push    ax
    
            mov     bl, 100             ; divide ax by 100.
            div     bl
            mov     ah, 0
    
            call    prt_digit
    
            mul     bl                  ; remove hundreds digit.
            mov     bx, ax
            pop     ax
            sub     ax, bx
    
    skip_h:
            cmp     ax, 10
            jl      skip_t
    
            push    ax
    
            mov     bl, 10              ; divide ax by 10.
            div     bl
            mov     ah, 0
    
            call    prt_digit
    
            mul     bl                  ; remove tens digit.
            mov     bx, ax
            pop     ax
            sub     ax, bx
    
    skip_t:
            call    prt_digit
    
            mov     dx, offset eoln
            mov     ah, 9
            int     021h
    
            pop     dx
            pop     bx
            pop     ax
            ret
    
    prt_digit:
            push    ax                  ; save registers.
            push    dx
    
            mov     dx, ax              ; put in correct register.
            add     dx, '0'             ; turn into digit.
            mov     ah, 2               ; print.
            int     021h
    
            pop     dx                  ; restore registers and return.
            pop     ax
            ret