Assembly 调用修复数组过程似乎导致了无限循环
我写这段代码是为了用视频ram画一个形状。每当我Assembly 调用修复数组过程似乎导致了无限循环,assembly,masm,x86-16,dosbox,Assembly,Masm,X86 16,Dosbox,我写这段代码是为了用视频ram画一个形状。每当我调用fixarray时,它似乎进入了一个无限循环。您能帮忙吗?我发布了一大块代码,因此任何人都可以重新生成它并找出问题的原因 Data_segment_name segment para hhead dw ? ;head h dw 12 dup (?) ;array hlength dw ?
调用fixarray
时,它似乎进入了一个无限循环。您能帮忙吗?我发布了一大块代码,因此任何人都可以重新生成它并找出问题的原因
Data_segment_name segment para
hhead dw ? ;head
h dw 12 dup (?) ;array
hlength dw ? ;array length
htail dw ? ;array tail
Data_segment_name ends
Stack_segment_name segment para stack
dw 16 dup(0) ;define your stack segment
Stack_segment_name ends
Code_segment_name segment
Main_prog proc far
assume SS:Stack_segment_name,CS:Code_segment_name,DS:Data_segment_name
mov AX,Data_segment_name ;load the starting address of the data
mov DS,AX ; segment into DS reg.
call cls
call drawh
call movehu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,4c00h ; exit program
int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
fixharr proc near
;fix array positions
mov cx,hlength-1 ;i.e (don't need old tail)
fixarr:
mov si,cx
add si,si ;scale si to 2
mov ax,h[si-2]
mov h[si],ax
loop fixarr
mov ax,hhead
mov h[0],ax
ret
fixharr endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
drawh proc near ;draw array
push ax
push cx
mov di,160*9+20*2
mov hhead,di
mov si,0
mov h[si],di ;save head position
inc si
mov hlength,si ;length = si+1 i.e. h[0]=position length=1
mov ax,0b800h
mov es,ax
mov ax, 1f2ah ;draw head
std
stosw
mov cx,2
label1:
;draw array
mov h[si],di ;save body position (si is already incremented)
mov htail,di
inc si ;to be ready for next insertion
mov hlength,si
mov ax,0b800h
mov es,ax
mov ax, 112ah
std
stosw
loop label1
pop cx
pop ax
ret
drawh endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
movehu proc near
mov ax,hhead ;remove old head
mov di,hhead
mov ax,0b800h
mov es,ax
mov ax,112ah
stosw
mov ax,hhead ;draw new head (without deleting old head)
sub ax,160
mov hhead,ax
mov di,hhead
mov ax,0b800h
mov es,ax
mov ax,1f2ah
stosw
;delete tail
mov di,htail
mov ax,0b800h
mov es,ax
mov ax,002ah
cld
stosw
mov htail,di
;fix array positions
call fixharr
ret
movehu endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cls proc near
mov ax,0b800h
mov es,ax
mov ax,0720h
mov di,0
mov cx,2000
rep stosw
ret
cls endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Code_segment_name ends
end Main_prog
这就是为什么MCVE很重要。 现在我们知道,您将
hlength
声明为内存中的变量,而不是常量。对于常数,您可以执行mov-cx,hllength-1
,但对于不执行您认为的操作的变量。用“括号语法”重写,即mov-cx,[hlength-1]
,从内存中的地址hlength-1
加载一个字。它不会从addresshlength
加载一个字,然后将其递减。要实现这一点(因为这是您真正想要的),您应该:
mov cx, hlength
dec cx
(或同等标准)
PS:我们已经告诉过您,问题可能是长度问题,即使没有看到完整的代码。学习使用调试器。答案很好。另一个注意事项是,如果
hllength
可以为零,则循环将执行64k次。很可能不是我们想要的。非常感谢@jester,是的,你是对的,从现在起我将尝试发布MCVE。我不知道我们可以在汇编中定义一个常量。我尝试了上面的代码,现在它工作了。再次感谢你,我认为HLENGHT不能为零,但如果出现这种情况,我该怎么办?我不明白这个循环怎么能执行64k次。我以为它会在cx=0时结束,对吗?@gene