2016-06-25 2 views
-3

Мне нужно нарисовать квадрат в сборе x86. Я знаю, как рисовать квадрат, но моя проблема в том, что у меня много переменных, и я не хочу делать процедуру для каждой переменной 2 (x и y). Я добавил пример, где я определяю x и y. Это то, что я пытался сделать:Сборка x86 - проблемы с рисованием квадратного графического режима

proc ChangeColumn4Number4 
    inc [FourthColumnArray + 3] 
    mov [Player1Drawx], 85h 
    mov [Player1Drawy], 27h 
    jmp DrawPlayer1Disc 
endp ChangeColumn4Number4 

DrawPlayer1Loop: 
    mov bh,0h 
    mov cx,[Player1Drawx] 
    mov dx,[Player1Drawy] 
    mov al,[player1disccolor] 
    mov ah,0ch 
    int 10h 
    add [Player1Drawx], 1h 
    mov ax, dx 
    add ax, 14h 
    cmp dx, ax 
    jl DrawPlayer1Loop 

DrawPlayer1Disc: 
    mov bh, 0h 
    mov dx, [Player1Drawy] 
    add [Player1Drawy], 1h 
    mov ax, dx 
    add ax, 14h 
    cmp dx, ax 
    jl DrawPlayer1Loop 

Кто-то с этого сайта направляемой сделать это таким образом, но это не работает. Спасибо за помощь.

+0

В первом цикле то, что именно является точкой перемещения y-координаты на 'ax', добавляя' 14h' и сравнивая ее с исходным значением? Филиал 'jl' никогда не будет принят. –

+0

@WeatherVane Спасибо за ответ. Я думал об этом раньше, и я был уверен, что я не понял его правильно, потому что человек, который сказал мне сделать это, имел 4000 репутации. Что я должен сделать вместо этого, чтобы исправить это? Я весь день ломаю голову, пытаясь это исправить. – KatomPower

+0

Размер квадрата не отображается в коде. Вы должны перебирать координату x до тех пор, пока она не достигнет (startx + dimension). В то же время вы можете построить другой параллельный фронт с другой y-координатой (starty + dimension). Затем повторите упражнение для вертикальных краев. –

ответ

2

Адаптация кода. Для этого нужны четыре переменные: верхние левые координаты, цвет и квадратный размер. Я также показываю, как квадратный размер может быть жестко закодирован. Я написал его слепой, так как у меня нет DOSBOX - надеюсь, он работает, поэтому вы можете его использовать.

DrawSquare: 
    mov dx,[Player1Drawy]  ;top edge 
    mov di,[SideLength]   ;control y loop 
    ;mov di,14h     ;or this, if the side length is fixed 

SquareYloop: 
    mov cx,[Player1Drawx]  ;left edge 
    mov si,[SideLength]   ;control x loop 
    ;mov si,14h     ;or this, if the side length is fixed 

SquareXloop: 
    push cx      ;I don't know if these 4 pushes are necessary... 
    push dx 
    push si 
    push di 

    mov bh,0h     ;video page 
    mov al,[player1disccolor] ;colour 
    mov ah,0ch     ;draw pixel function 
    int 10h      ;BIOS video interrupt 

    pop di      ;... or these 4 matching pops are necessary 
    pop si      ;depends on whether int 10h func corrupts them 
    pop dx 
    pop cx 

    inc cx      ;advance X position 
    dec si      ;count side of square to control the loop 
    jne SquareXloop    ;next horizontal pixel 

    inc dx      ;advance Y position 
    dec di      ;count side of square to control the loop 
    jne SquareYloop    ;next row 
2

Используйте этот код, либо в качестве шаблона, отправной точкой или как это:

;X   +0ah 
;Y   +08h 
;Size  +06h 
;Color  +04h 
drawSquare: 
push bp 
mov bp, sp 

pusha      ;Push all, can replace with single pushes 

mov ax, WORD [bp+04h] 
mov ah, 0ch    ;AH = 0ch, AL = Color 

xor bx, bx     ;Page 0 
mov dx, WORD [bp+08h]  ;DX = Y coord 

mov si, WORD [bp+06h]  
mov di, si 
add di, dx     ;DI = Size + Y 
add si, WORD [bp+0ah]  ;SI = Size + X 

__ds_drawSquare: 
    mov cx, WORD [bp+0ah]  ;CX = X Coord 

___ds_drawRow: 

    int 10h 

    add cx, 01h    ;Increment X coord 
    cmp cx, si 
    jb ___ds_drawRow   ;Stay in the same row if X < Initial X + Size 

    add dx, 01h    ;Increment Y coord 
    cmp dx, di 
jb __ds_drawSquare   ;Keep drawing rows if Y < Initial Y + Size 

popa      ;See pusha above 

pop bp 
ret 08h 

код достаточно просто не требуют никаких дополнительных объяснений.
Параметры передаются в стеке, здесь случай использования

BITS 16 

ORG 100h 

mov ax, 0013h 
int 10h 

push 10 
push 30 
push 40 
push 0ch 
call drawSquare 

push 20 
push 80 
push 30 
push 06h 
call drawSquare 

push 200 
push 100 
push 60 
push 09h 
call drawSquare 

push 270 
push 140 
push 50 
push 07h 
call drawSquare 

push 10 
push 30 
push 40 
push 0ch 
call drawSquare 

push 30 
push 110 
push 40 
push 03h 
call drawSquare 

xor ah, ah 
int 16h 

mov ax, 4c00h 
int 21h 

Который производит

Squares on the screen

код для NASM, адаптировать его к тому, что ассемблер вы используете.


Рисунок внутри диапазона видеобуфера вашей ответственности.

+0

Спасибо за помощь. Я новичок в сборке x86, и я использую TASM, чтобы все, что вы написали в NASM, было похоже на китайский язык. Можете ли вы каким-либо образом адаптировать его к TASM? – KatomPower

+1

Синтаксис ассемблерного кода Маргарет в значительной степени как и ваша. Возможно, сложность заключается в ее номенклатуре метки или адресной реестре, которая показывает, как вы можете передавать аргументы через стек, вместо того, чтобы иметь фиксированные ячейки памяти для них. Обратите внимание, как она толкает аргументы для каждого другого квадрата в стек , которые извлекаются функцией с использованием регистра 'BP'. Это довольно стандартная практика и использует« BP »так, как планировали разработчики процессоров. –

Смежные вопросы