Asm Assembler - цикл CX никогда не выполняется - PullRequest
2 голосов
/ 06 мая 2019

У меня есть вектор, и я должен ввести в регистр AX сумму чисел, превышающих 50 (> 50).

Я не понимаю, почему мой цикл не работает, когдаЯ запускаю это.Сначала он сравнивает 100 с 50, прыгает на adunare , добавляет 100 к AX, но затем выходит из цикла и завершает программу.

.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

1 Ответ

2 голосов
/ 07 мая 2019
.STACK 10h

При таком маленьком стеке отладчик вполне может завершить вашу программу, как только произойдет прерывание, и вы будете думать, что цикл не выполняется.
Укажите больший стек. 256 байтов - разумный минимум.

adunare:
    add ax, word ptr vect[si]

Чтобы добавить байт в vect[si] к слову в AX, у вас есть несколько вариантов:

  • с использованием промежуточного регистра , как предложил zx485

    • очистка дополнительного регистра:

      xor     dx, dx
      mov     dl, vect[si]
      add     ax, dx
      
    • расширение от байта к слову в одной инструкции:

      movzx   dx, vect[si]
      add     ax, dx
      
  • без дополнительного регистра, но с использованием каскадного дополнения:

    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

Вы можете написать это проще, и если бы число 50 присутствовало в массиве, оно было бы ошибочно добавлено к сумме. Помимо условий выше и ниже есть также условие равно .

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

Для совершенства вы можете отклонить инструкцию loop (она имеет репутацию медленной) и использовать вместо нее dec cx jnz bucla. Это в свою очередь дает вам возможность не иметь нуля CH, а скорее использовать dec cl jnz bucla.

Все вместе:

    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

Я протестировал множество вариантов.
Это более быстрая версия цикла:

    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
...