Assembly 调用修复数组过程似乎导致了无限循环

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 ?

我写这段代码是为了用视频ram画一个形状。每当我
调用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
加载一个字。它不会从address
hlength
加载一个字,然后将其递减。要实现这一点(因为这是您真正想要的),您应该:

mov cx, hlength
dec cx
(或同等标准)


PS:我们已经告诉过您,问题可能是长度问题,即使没有看到完整的代码。学习使用调试器。

答案很好。另一个注意事项是,如果
hllength
可以为零,则循环将执行64k次。很可能不是我们想要的。非常感谢@jester,是的,你是对的,从现在起我将尝试发布MCVE。我不知道我们可以在汇编中定义一个常量。我尝试了上面的代码,现在它工作了。再次感谢你,我认为HLENGHT不能为零,但如果出现这种情况,我该怎么办?我不明白这个循环怎么能执行64k次。我以为它会在cx=0时结束,对吗?@gene