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

时间:2015-12-23 12:06:59

标签: assembly masm x86-16 dosbox

我编写了这段代码,用于使用视频ram绘制形状。每当我call 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

1 个答案:

答案 0 :(得分:2)

看,这就是MCVE很重要的原因。 现在我们知道您将hlength声明为内存中的变量而不是常量。对于常量,你可以mov cx, hlength-1但是对于一个不符合你想象的变量。重写“括号语法”mov cx, [hlength-1],它从地址hlength-1的内存加载一个单词。它不会从地址hlength加载一个单词,随后递减它。要实现这一目标(因为这是你真正想要的),你应该这样做:

mov cx, hlength
dec cx

(或同等)

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