【发布时间】:2020-12-23 17:44:37
【问题描述】:
我最近开始学习组装 (TASM),目前正在学习如何正确更改不同形状的位置。
我有以下代码:
.model small
.stack 100h
.data
; codes returned int 16h ah = 00h
; the arrows we control
kbArrowUp equ 4800h
kbArrowDown equ 5000h
kbArrowLeft equ 4B00h
kbArrowRight equ 4D00h
kbEsc equ 011Bh
; color codes of symbols and points in graphic mode
Red equ 4
Gray equ 7
Blue equ 1
White equ 15
Mode0D_W equ 320 ; screen width in pixels for video mode 0Dh
Mode0D_H equ 200 ; screen height in pixels for video mode 0Dh
Mode0D_C equ 16 ; number of colors for video mode 0Dh
Mode0D_A equ 0A000h ; starting address of video memory for video mode 0Dh
VideoPage db ? ;video page number
Xstart dw 100 ; coordinates of the beginning of the square
Ystart dw 70
sqColor dw 1 ; color of the rendered rectangle
sqWidth dw 40 ; rectangle width
sqHeight dw 40 ; height of the rectangle
XstartS dw 150 ;coordinates of the beginning of the square
YstartS dw 70
sqColorS dw 1 ;color of the rendered rectangle
sqWidthS dw 15 ;rectangle width
sqHeightS dw 80 ;height of the rectangle
; macro to simplify calling procedures with parameters
invoke macro CallProc, Params
IRP P, <Params>
mov ax, P
push ax
endm
call CallProc
endm
.code
main proc
mov ax, @data
mov ds, ax
; setting graphics video mode
mov ax, 000Dh
int 10h
mov ah, 0Fh ; clarification of video mode parameters
int 10h
mov [VideoPage], bh
invoke Bar, <[sqHeight], [sqWidth], [Ystart], [Xstart], [sqColor] >
@@GetCmd:
; waiting for any key
mov ah, 00h
int 16h
;обработка команды
@@TestCmd1:
cmp ax, kbArrowUp
jne @@TestCmd2
mov dx, [Ystart]
cmp dx, 0
je @@GetCmd
dec dx
mov cx, [Xstart]
jmp @@Redraw
@@TestCmd2:
cmp ax, kbArrowDown
jne @@TestCmd3
mov dx, [Ystart]
add dx, [sqWidth]
cmp dx, Mode0D_H
jae @@GetCmd
mov dx, [Ystart]
inc dx
mov cx, [Xstart]
jmp @@Redraw
@@TestCmd3:
cmp ax, kbArrowLeft
jne @@TestCmd4
mov cx, [Xstart]
cmp cx, 0
je @@GetCmd
dec cx
mov dx, [Ystart]
jmp @@Redraw
@@TestCmd4:
cmp ax, kbArrowRight
jne @@TestCmd5
mov cx, [Xstart]
add cx, [sqWidth]
cmp cx, Mode0D_W
jae @@GetCmd
mov cx, [Xstart]
inc cx
mov dx, [Ystart]
jmp @@Redraw
@@TestCmd5:
cmp ax, kbEsc
jne @@TestCmd1S
jae @@GetCmdS
invoke Bar, <[sqHeightS], [sqWidthS], [YstartS], [XstartS], [sqColorS] >
@@GetCmdS:
;ожидание нажатия любой клавиши
mov ah, 00h
int 16h
;обработка команды
@@TestCmd1S:
cmp ax, kbArrowUp
jne @@TestCmd2S
mov dx, [YstartS]
cmp dx, 0
jae @@GetCmdS
dec dx
mov cx, [XstartS]
jmp @@Redraw
@@TestCmd2S:
cmp ax, kbArrowDown
jne @@TestCmd3S
mov dx, [YstartS]
add dx, [sqWidthS]
cmp dx, Mode0D_H
jae @@GetCmdS
mov dx, [YstartS]
inc dx
mov cx, [XstartS]
jmp @@Redraw
@@TestCmd3S:
cmp ax, kbArrowLeft
jne @@TestCmd4S
mov cx, [XstartS]
cmp cx, 0
je @@GetCmdS
dec cx
mov dx, [YstartS]
jmp @@Redraw
@@TestCmd4S:
cmp ax, kbArrowRight
jne @@TestCmd5S
mov cx, [XstartS]
add cx, [sqWidthS]
cmp cx, Mode0D_W
jae @@GetCmdS
mov cx, [XstartS]
inc cx
mov dx, [YstartS]
jmp @@Redraw
@@TestCmd5S:
cmp ax, kbEsc
jne @@GetCmdS
jmp @@StopCmdLoop
@@Redraw:
invoke Bar, <[sqHeight], [sqWidth], [Ystart], [Xstart], 0>
mov ax, [sqColor]
inc ax ;Color++
cmp ax, Mode0D_C ;if (Color>MaxColor)
sbb bx, bx ; Color=1
and ax, bx
cmp ax, 1
adc ax, 0
mov [sqColor], ax
mov [Xstart], cx
mov [Ystart], dx
invoke Bar, <[sqHeight], [sqWidth], dx, cx, [sqColor]>
jmp @@GetCmd
@@RedrawS:
invoke BarS, <[sqHeightS], [sqWidthS], [YstartS], [XstartS], 0>
mov ax, [sqColorS]
inc ax ;Color++
cmp ax, Mode0D_C ;if (Color>MaxColor)
sbb bx, bx ; Color=1
and ax, bx
cmp ax, 1
adc ax, 0
mov [sqColorS], ax
mov [XstartS], cx
mov [YstartS], dx
invoke BarS, <[sqHeightS], [sqWidthS], dx, cx, [sqColor]>
jmp @@GetCmdS
@@StopCmdLoop:
;переключение в текстовый режим
mov ax, 0003h
int 10h
;завершение программы
mov ax, 4C00h
int 21h
main endp
;рисование полосы (залитого прямоугольника)
;на входе:
; color - цвет заливки
; x_pos, y_pos - координаты левого верхнего угла
; x_size, y_size - размеры прямоугольника
;на выходе:
; -
Bar proc color: word, x_pos:word, y_pos: word, x_size: word, y_size: word
push bp ;формирование кадра параметров
mov bp, sp
push ax ;сохранение регистров
push bx
push cx
push dx
push si
push di
mov ah, 0Ch ; настройка параметров для вызова функции 0Ch
mov al, byte ptr color ;цвет точек
mov bh, 0 ;номер видеостраницы
mov dx, y_pos ;строка
mov cx, x_pos ;колонка
mov di, y_size
@@Vertical:
mov cx, x_pos ;колонка
mov si, x_size ;вывести x_size точек в горизонтальной линии
@@Horizontal:
int 10h ;вывести точку
inc cx ;прирастить координату x
dec si
jnz @@Horizontal
inc dx ;переход к следующей горизонтальной линии с
dec di
jnz @@Vertical
pop di ;восстановление рагистров
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 10 ;удаление параметров из стека
Bar endp
BarS proc colorS: word, x_posS:word, y_posS: word, x_sizeS: word, y_sizeS: word
push bp ;формирование кадра параметров
mov bp, sp
push ax ;сохранение регистров
push bx
push cx
push dx
push si
push di
mov ah, 0Ch ; настройка параметров для вызова функции 0Ch
mov al, byte ptr colorS ;цвет точек
mov bh, 0 ;номер видеостраницы
mov dx, y_posS ;строка
mov cx, x_posS ;колонка
mov di, y_sizeS
@@VerticalS:
mov cx, x_posS ;колонка
mov si, x_sizeS ;вывести x_size точек в горизонтальной линии
@@HorizontalS:
int 10h ;вывести точку
inc cx ;прирастить координату x
dec si
jnz @@Horizontal
inc dx ;переход к следующей горизонтальной линии с
dec di
jnz @@Vertical
pop di ;восстановление рагистров
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 10 ;удаление параметров из стека
BarS endp
end main
有一件事我不明白:
当我更改矩形的坐标(XstartS 和 YstartS)时,矩形的位置不会改变。
我希望矩形居中并位于正方形下方,如下所示:
你能解释一下吗:
- 为什么在这段代码中,一个矩形在坐标改变时不移动?
- 正确的代码应该是什么样的,这样结果才能像第二个屏幕截图一样显示?
【问题讨论】:
标签: animation assembly x86-16 tasm