将mov从di寄存器用于变量时的值会发生变化

时间:2016-06-26 21:50:28

标签: assembly x86-16 tasm

我的代码中存在问题。

我正在尝试将DI寄存器的值移动到名为 var 的变量中。 DI寄存器中的值可以是0,1,2或3(随机选择),但是当我将其移动到 var 时,值将更改为514(I使用调试器中的watch功能来查看) 问题出现在“游戏”标签下的第440行。

    IDEAL
    MODEL small
    STACK 100h
    DATASEG
    x dw 80
    y dw 64
    green db 2
    red db 4
    yellow db 14
    blue db 1
    white db 15
    arr dw 11 dup(4)
    Clock equ es:6Ch
    hold db 0
    key db 0
    marker dw 0
    var dw ?
    CODESEG
    proc YellowP
        mov[x], 80
        mov[y], 64
        yLoop:
            mov bh,0h
            mov cx,[x]
            mov dx,[y]
            mov al,[yellow]
            mov ah,0ch
            int 10h
            inc [x]
            cmp cx, 112
            jl yLoop    
        ySquare:
            mov bh, 0h
            inc [y]
            mov [x], 80
            cmp dx, 96
            jl yLoop
        ret 
        endp YellowP
    proc BlueP
        mov[x], 113
        mov[y], 64      
        bLoop:
            mov bh, 0h
            mov cx, [x]
            mov dx, [y]
            mov al, [blue]
            mov ah, 0ch
            int 10h
            inc [x]
            cmp cx, 144
            jl bLoop    
        bSquare:
            mov bh, 0h
            inc [y]
            mov [x], 113
            cmp dx, 96
            jl bLoop
        ret
        endp BlueP
    proc GreenP
        mov[x],80
        mov[y],32   
        gLoop:
            mov bh, 0h
            mov cx, [x]
            mov dx, [y]
            mov al, [green]
            mov ah, 0ch
            int 10h
            inc [x]
            cmp cx, 112
            jl gLoop    
        gSquare:
            mov bh, 0h
            inc [y]
            mov [x], 80
            cmp dx, 64
            jl gLoop
        ret
        endp GreenP
    proc RedP
        mov[x],112
        mov[y],32
        rLoop:
            mov bh, 0h
            mov cx, [x]
            mov dx, [y]
            mov al, [red]
            mov ah, 0ch
            int 10h
            inc [x]
            cmp cx, 144
            jl rLoop    
        rSquare:
            mov bh, 0h
            inc [y]
            mov [x], 112
            cmp dx, 64
            jl rLoop
        ret
        endp RedP
    ;===============================================================
    ;===============================================================
    proc Random
        RND:
            mov ax, 40h
            mov es, ax
            mov ax, [es:6Ch]
            and al, 00000011b
            xor ah, ah
            mov di, ax
            cmp al, 0
            je GreenPress
            cmp al, 1
            je RedPress
            cmp al, 2
            je YellowPress
            jg BlueMid  
        GreenPress:
            mov[x],80
            mov[y],32
            g2Loop:
                mov bh, 0h
                mov cx, [x]
                mov dx, [y]
                mov al, [white]
                mov ah, 0ch
                int 10h
                inc [x]
                cmp cx, 112
                jl g2Loop   
            g2Square:
                mov bh, 0h
                inc [y]
                mov [x], 80
                cmp dx, 64
                jl g2Loop
        ret
        RedPress:
            mov[x],112
            mov[y],32
            r2Loop:
                mov bh, 0h
                mov cx, [x]
                mov dx, [y]
                mov al, [white]
                mov ah, 0ch
                int 10h
                inc [x]
                cmp cx, 144
                jl r2Loop   
            r2Square:
                mov bh, 0h
                inc [y]
                mov [x], 112
                cmp dx, 64
                jl r2Loop
        ret
        BlueMid:
            jmp BluePress
        YellowPress:
            mov[x], 80
            mov[y], 64
            y2Loop:
                mov bh,0h
                mov cx,[x]
                mov dx,[y]
                mov al,[white]
                mov ah,0ch
                int 10h
                inc [x]
                cmp cx, 112
                jl y2Loop   
            y2Square:
                mov bh, 0h
                inc [y]
                mov [x], 80
                cmp dx, 96
                jl y2Loop
        ret     
        BluePress:
            mov[x], 113
            mov[y], 64
            b2Loop:
                mov bh, 0h
                mov cx, [x]
                mov dx, [y]
                mov al, [white]
                mov ah, 0ch
                int 10h
                inc [x]
                cmp cx, 144
                jl b2Loop   
            b2Square:
                mov bh, 0h
                inc [y]
                mov [x], 113
                cmp dx, 96
                jl b2Loop
        ret
        endp Random
    proc second
        mov ax, 40h
        mov es, ax
        mov ax, [Clock]
        FirstTick:
        cmp ax, [Clock]
        je FirstTick
        mov cx, 9
        DelayLoop:
            mov ax, [Clock]
        Tick:
        cmp ax, [Clock]
        je Tick
        loop DelayLoop
        ret
        endp second
    ;===============================================================
    ;===============================================================
    proc Gpress
            mov[x],80
            mov[y],32
            g3Loop:
                mov bh, 0h
                mov cx, [x]
                mov dx, [y]
                mov al, [white]
                mov ah, 0ch
                int 10h
                inc [x]
                cmp cx, 112
                jl g3Loop   
            g3Square:
                mov bh, 0h
                inc [y]
                mov [x], 80
                cmp dx, 64
                jl g3Loop
            ret
            endp Gpress
    proc Rpress
        mov[x],112
        mov[y],32
        r3Loop:
            mov bh, 0h
            mov cx, [x]
            mov dx, [y]
            mov al, [white]
            mov ah, 0ch
            int 10h
            inc [x]
            cmp cx, 144
            jl r3Loop   
        r3Square:
            mov bh, 0h
            inc [y]
            mov [x], 112
            cmp dx, 64
            jl r3Loop
        ret
        endp Rpress
    proc Ypress
        mov[x], 80
        mov[y], 64
        y3Loop:
            mov bh,0h
            mov cx,[x]
            mov dx,[y]
            mov al,[white]
            mov ah,0ch
            int 10h
            inc [x]
            cmp cx, 112
            jl y3Loop   
        y3Square:
            mov bh, 0h
            inc [y]
            mov [x], 80
            cmp dx, 96
            jl y3Loop   
        ret
        endp Ypress
    proc Bpress
        mov[x], 113
        mov[y], 64
        b3Loop:
            mov bh, 0h
            mov cx, [x]
            mov dx, [y]
            mov al, [white]
            mov ah, 0ch
            int 10h
            inc [x]
            cmp cx, 144
            jl b3Loop   
        b3Square:
            mov bh, 0h
            inc [y]
            mov [x], 113
            cmp dx, 96
            jl b3Loop
        ret
        endp Bpress
    proc RNDsquare
        call second
        call random
        call second
        cmp di, 0
        je aG
        cmp di, 1
        je aR
        cmp di, 2
        je aY
        jg aB
        aG:
            call GreenP
            jmp endproc
        aR:
            call RedP
            jmp endproc
        aY:
            call YellowP
            jmp endproc
        aB:
            call BlueP
            jmp endproc
        endproc:
            ret
            endp RNDsquare
    proc CheckArr
        mov si, 0
        check:
            cmp [arr + si], 0
            je tempo1
            cmp [arr + si], 1
            je tempo2
            cmp [arr + si], 2
            je tempo3
            cmp [arr + si], 3
            je tempo4
            jg tempo
            tempo1:
                call second
                call Gpress
                call second
                call GreenP
                inc si
                jmp check
            tempo2:
                call second
                call Rpress
                call second
                call RedP
                inc si
                jmp check
            tempo3:
                call second
                call Ypress
                call second
                call YellowP
                inc si
                jmp check
            tempo4:
                call second
                call Bpress
                call second
                call BlueP
                inc si
                jmp check
            tempo:
                mov si, 0
                ret
                endp CheckArr
    ;===============================================================
    ;===============================================================                            
    start:
    mov ax, @data
    mov ds, ax  
    ; Graphic mode
    mov ax, 13h
    int 10h
    call YellowP
    call GreenP
    call BlueP
    call RedP   
    call RNDsquare
    mov [arr + 0], di
    mov ah, 1
    int 21h
    mov [key], al
    cmp di, 0
    je temp1
    cmp di, 1
    je temp2
    cmp di, 2
    je temp3
    jg temp4
    temp1:
        cmp [key], 113
        jne nextmid
        call Gpress
        call second
        call GreenP
        je prog
    temp2:
        cmp [key], 119
        jne nextmid
        call Rpress
        call second
        call RedP
        je prog
    temp3:
        cmp [key], 97
        jne nextmid
        call Ypress
        call second
        call YellowP
        je prog
    temp4:
        cmp [key], 115
        jne nextmid
        call Bpress
        call second
        call BlueP
        je prog
    ;=========================================after round 1
    nextmid:
        jmp next
    prog:
        call CheckArr
        cmp [arr + 12], 4
        jne nextmid2
        inc [marker]
        mov si, [marker]
        call RNDsquare
        mov [arr + si], di
        mov si, 0
    game:
        mov di, [arr + si]
        mov [var], di
        cmp [var], 0
        je game0
        cmp [var], 1
        je game1
        cmp [var], 2
        je game2
        cmp [var], 3
        je game3
        jmp prog
        game0:
            mov ah, 1
            int 21h
            cmp al, 113
            jne next
            call Gpress
            call second
            call GreenP
            inc si
            jmp game
        game1:
            mov ah, 1
            int 21h
            cmp al, 119
            jne next
            call Rpress
            call second
            call RedP
            inc si
            jmp game
    nextmid2:
        jmp next
        game2:
            mov ah, 1
            int 21h
            cmp al, 97
            jne next
            call Ypress
            call second
            call YellowP
            inc si
            jmp game
        game3:
            mov ah, 1
            int 21h
            cmp al, 115
            jne next
            call Bpress
            call second
            call BlueP
            inc si
            jmp game
    next:
        ; Wait for key press
         mov ah,00h
         int 16h
        ; Return to text mode
        mov ah, 0
        mov al, 2
        int 10h
    exit:
        mov ax, 4c00h
        int 21h
    END start

2 个答案:

答案 0 :(得分:1)

arr dw 11 dup(4)

您的程序的基本问题是您已将数组 arr 定义为 word ,但您反复遍历数组,就好像它包含字节一样即可。
重新定义阵列将是最好的,并将避免大量其他修改。所以我建议一个简单的解决方案,以便能够继续使用DI寄存器:

arr db 11 dup(4)
...
game:
    mov di, [arr + si]
    and di, 255      <<<< removes the garbage high byte!
    mov [var], di

这样mov di, [arr + si]指令遗憾地读取了一个垃圾字节,但是下面的and di, 255只是清除它。简单而且省力。

您的程序中有一个位于数组中的位置。这里只是编写DI寄存器不再是一个选项。您将不得不使用字节大小的寄存器:

    mov ax, di            ;Temporarily copy to splittable register
    mov [arr + si], al    ;Only write the low byte
    mov si, 0
game: 

我认为阵列不够大。在一行中你写了cmp [arr + 12], 4。这没有意义!对于字大小的数组,它指向中间的某个位置,对于字节大小的数组,它将指向数组 您使用值 4 初始化数组这一事实意味着您需要检查数组中的最后一个元素。这是在11个元素字节大小的数组中的偏移量10。

arr db 11 dup(4)
...
prog:
    call CheckArr
    cmp [arr + 10], 4   <<< checks last element!

答案 1 :(得分:0)

快速查看game:

以下的猜测
    mov di, [arr + si]
    mov [var], di

di是16b寄存器,所以你从[arr + si]中取出 word (16b),你准备了一些随机0-3 字节(8b)我猜?

5140x0202,实际上它看起来像是两个字节2

因此,如果var为16b,而arr为8b源代码,则可以通过各种方式进行修复,然后使用:

    movzx di, byte [arr + si]  ; fetch only 8b from []
        ; and extend them to 16b with zeroes (zx = zero extended)
        ; (similar instruction movsx extends with sign bit)
    mov [var], di   ; store the converted 0-3 16b value to var

编辑: 虽然你的arr dw 11 dup(4)定义表明arr意在用作16b数组,但真正的问题可能在你的随机0-3生成器中,存储字节而不是字。然后在game标签下不需要修复,但在其他地方不需要(我没有费心去搜索arr生成器)。