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