Asm汇编器-CX循环永远不会执行

时间:2019-05-06 13:57:06

标签: loops assembly dos x86-16

我有一个向量,必须将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 个答案:

答案 0 :(得分:2)

.STACK 10h

使用如此小的堆栈,调试器很可能在发生中断后立即终止程序,使您认为循环不会执行。
指定更大的堆栈。 256个字节是一个合理的最小值。

adunare:
    add ax, word ptr vect[si]

要将vect[si] byte 添加到AX word 中,您可以使用以下几种选择:

  • 使用中间寄存器like zx485 suggested

    • 清除多余的寄存器:

      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,则会将其错误地加到总和上。除了 above below 条件之外,还有 equal 条件需要照顾。

    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