在程序集8086中拖放项目(用鼠标移动一个方块)

问题描述 投票:0回答:1

我是一名计算机科学学生,我需要为我的建筑课构建一个项目。我尝试在 asm 中构建一个简单的拖放程序。整个想法是在屏幕上的某处绘制一个正方形,然后使用鼠标将其拖动到其他位置,就像在常规桌面上一样。

我尝试过使用缓冲区,但没有效果。我太初学者了,无法让它发挥作用。所以我尝试了一些函数来重画正方形。这是我使用 Copilot 得到的最好结果:

.model small
.stack 100h
.data
    x dw 100           ; Initial x position of square
    y dw 100           ; Initial y position of square
    size_square dw 50  ; Size of the square
    isDragging db 0    ; Flag to check if the square is being dragged
    prev_x dw 100      ; Previous x position of square
    prev_y dw 100      ; Previous y position of square

.code
start:
    ; Initialize graphics mode
    mov ax, 13h
    int 10h

    ; Initialize mouse
    mov ax, 0
    int 33h
    mov ax, 1
    int 33h

    ; Hide mouse cursor
    mov ax, 2
    int 33h

    ; Draw initial square
    call draw_square

main_loop:
    ; Show mouse cursor
    mov ax, 1
    int 33h

    ; Get mouse status
    mov ax, 3
    int 33h

    ; Check if left button is pressed
    test bx, 1
    jz no_drag

    ; Start dragging
    mov isDragging, 1
    mov prev_x, cx
    mov prev_y, dx

dragging:
    ; Hide mouse cursor while dragging
    mov ax, 2
    int 33h

    ; Get mouse status
    mov ax, 3
    int 33h

    ; Check if button is still pressed
    test bx, 1
    jz stop_drag

    ; Clear previous square position
    call clear_square

    ; Update square position
    mov x, cx
    mov y, dx

    ; Draw square at new position
    call draw_square

    ; Store current position as previous position
    mov prev_x, x
    mov prev_y, y

    jmp dragging

no_drag:
    ; If not dragging, wait for next mouse event
    jmp main_loop

stop_drag:
    ; Stop dragging
    mov isDragging, 0
    ; Show mouse cursor
    mov ax, 1
    int 33h
    jmp main_loop

draw_square:
    ; Draw the square
    push si
    push di
    push cx
    push bx
    push dx
    mov cx, 0
draw_loop1:
    mov dx, 0
draw_loop2:
    mov ax, y
    add ax, cx
    mov si, ax
    mov ax, x
    add ax, dx
    mov di, ax
    mov al, 15
    mov ah, 0Ch
    int 10h

    inc dx
    cmp dx, size_square
    jl draw_loop2

    inc cx
    cmp cx, size_square
    jl draw_loop1

    pop dx
    pop bx
    pop cx
    pop di
    pop si
    ret

clear_square:
    ; Clear the previous square position
    push si
    push di
    push cx
    push bx
    push dx
    mov cx, 0
clear_loop1:
    mov dx, 0
clear_loop2:
    mov ax, prev_y
    add ax, cx
    mov si, ax
    mov ax, prev_x
    add ax, dx
    mov di, ax
    mov al, 0
    mov ah, 0Ch
    int 10h

    inc dx
    cmp dx, size_square
    jl clear_loop2

    inc cx
    cmp cx, size_square
    jl clear_loop1

    pop dx
    pop bx
    pop cx
    pop di
    pop si
    ret

exit_program:
    ; Restore text mode
    mov ax, 3
    int 10h
    ret

end start

请帮助我了解出了什么问题;(

assembly mouse x86-16
1个回答
0
投票

请帮助我了解出了什么问题;(

这个程序中很多地方都是错误的! AI 甚至无法使用 BIOS.WritePixel 在 (x,y) 处绘制实心正方形。 (屏幕左上角可能会显示一个实心白色方块)。为什么需要不同的代码来擦除正方形我无法理解。相同的过程,其他参数集。

push bx pop bx

BX 没有初始化为任何内容,那么为什么要浪费字节来保留 BX。

mov ax, y add ax, cx mov si, ax

BIOS.WritePixel 期望其 Y 坐标位于 DX 寄存器中,因此非常不是 SI。

mov ax, x add ax, dx mov di, ax

BIOS.WritePixel 期望其 X 坐标位于 CX 寄存器中,因此非常不是 DI。

我的版本:

mov cx, x mov dx, y mov al, 15 ; To 'clear' the square, you pass AL=0 call PaintSquare ... ; IN (al,cx,dx) PaintSquare: push bx ; AL is Color=[0,255] push si ; CX is X=[0,319] push di ; DX is Y=[0,199] mov bh, 0 ; DisplayPage mov di, size_square ; Height .OuterLoop: mov si, size_square ; Width .InnerLoop: mov ah, 0Ch ; BIOS.WritePixel int 10h inc cx ; X++ dec si jnz .InnerLoop sub cx, size_square inc dx ; Y++ dec di jnz .OuterLoop sub dx, size_square pop di pop si pop bx ret

prev_x dw 100 ; Previous x position of square prev_y dw 100 ; Previous y position of square

AI 正在加载

prev_xprev_y 以及记录鼠标点击的坐标。这与需要擦除方块的位置无关! 此外,在开始任何拖动之前,您仍然需要检查鼠标是否确实位于当前方块的顶部。

exit_program: ; Restore text mode mov ax, 3 int 10h ret

虽然 AI 包含了这个漂亮的“exit_program”部分,但该代码是无法访问的,如果跳转,它的

ret

 只能返回到 DOS,因为这是一个 .COM 可执行文件。遗憾的是,
.model small
 表示这将是一个 .EXE 可执行文件,另外未设置 DS 段寄存器,因此寻址基于内存的变量将完全失败。

这样的例子还在继续......


我的建议是你现在忘记使用鼠标,在我的PaintSquare程序的帮助下,你可以尝试使用基于箭头键移动方块的程序版本在键盘上。为了实现无闪烁图形,您可以使用双缓冲区,如您在评论之一中描述的。祝你好运。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.