alah
alah

Reputation: 21

Asm Assembler - CX loop never executes

I have a vector and I have to put in the AX register the sum of the numbers that are greater than 50 ( > 50 ).

I do not understand why my loop does not work when I run it. First it compares 100 with 50, jumps at adunare , add 100 to AX but then it exits the loop and terminates the program.

.MODEL SMALL
.STACK 10h
.DATA
vect DB 100,70,3,10,60,200,30
len DB 7
.CODE

begin:
    mov ax,@DATA
    mov ds,ax
    mov ax,0
    mov cl,len
    mov ch,0
    mov si, -1

bucla:
    inc si
    cmp vect[si],50
    ja adunare
    jb mic

adunare:
    add ax, word ptr vect[si]

mic:
    loop bucla
    mov ah,4ch
    int 21h

END begin

Upvotes: 2

Views: 103

Answers (1)

Sep Roland
Sep Roland

Reputation: 39691

.STACK 10h

With such a small stack the debugger could very well terminate your program as soon as an interrupt occurs, leaving you thinking that the loop doesn't execute.
Specify a larger stack. 256 bytes is a reasonable minimum.

adunare:
    add ax, word ptr vect[si]

To add the byte at vect[si] to the word in AX, you have several options:

  • using an intermediate register like zx485 suggested

    • clearing the extra register:

      xor     dx, dx
      mov     dl, vect[si]
      add     ax, dx
      
    • extending from byte to word in one instruction:

      movzx   dx, vect[si]
      add     ax, dx
      
  • without an extra register but using a cascaded addition:

    add     al, vect[si]
    adc     ah, 0
    
    cmp vect[si],50
    ja adunare
    jb mic
adunare:
    add ax, word ptr vect[si]
mic:
    loop bucla

You can write this simpler and if the number 50 were present in the array, it would erroneously be added to the sum. Besides the above and below conditions there's also the equal condition to take care of.

    cmp     vect[si], 50
    jna     mic
    add     al, vect[si]
    adc     ah, 0
mic:
    loop    bucla

For perfection you could dismiss the loop instruction (it has a reputation for being slow) and use instead dec cx jnz bucla. This in turn gives you the opportunity to not having to zero CH and rather use dec cl jnz bucla.

Everything together:

    xor     ax, ax      ; This makes AX=0
    mov     cl, len
    mov     si, -1
bucla:
    inc     si
    cmp     vect[si], 50
    jna     mic
    add     al, vect[si]
    adc     ah, 0
mic:
    dec     cl
    jnz     bucla
    mov     ah, 4ch     ; DOS.Terminate (exitcode is in AL)
    int     21h

I've tested a good number of variations.
This is a faster version of the loop:

    xor     ax, ax      ; This makes AX=0
    xor     si, si
    mov     cl, len
bucla:
    cmp     vect[si], 50
    jna     mic
    xor     dx, dx
    mov     dl, vect[si]
    add     ax, dx
mic:
    inc     si
    dec     cl
    jnz     bucla

Upvotes: 2

Related Questions