IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!

 
 Ответить  Открыть новую тему 
> Построение и управление квадратиками
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Имеется набор из 9-ти квадратиков. Выбор активного из них осуществляется нажатием соответствующей цифровой клавиши. Активный квадратик можно передвигать по полю, используя курсорные клавиши, а по нажатию "пробела" - менять его цвет. Написать программу построение различных фигур, испльзуя такой принцип управления.

Пока останавилась на построении набора квадратиков..Вот что получилось:

text	segment 'code' ; (1)  начало сегмента команд
              assume CS:text,DS:data; (2)
vertical	proc; (3)  объявление процедуры построения вертикальной линии
v:	; (4)    
	push	CX; (5)   сохраним в стек счетчик цикла
	mov	AH,0Ch; (6)  функция вывода пикселя
	mov	AL,6; (7)  установка цвета
	mov	BH,0; (8)  видеостраница
	mov	CX,SI; (9)  установка X-координаты
	int	10h; (10)  вызов BIOS
	inc	DX; (11)  счетчик Y-координаты 
	pop	CX; (12)  выгрузим из стека счетчик цикла
	loop	v; (13)  уменьшим его на единицу
ret; (14)  выход из подпрограммы
vertical	endp; (15)  конец текста подпрограммы
horizontal	proc; (16)  объявление процедуры построения горизонтальной линии
h:	; (17)
	push	CX; (18)  сохраним в стек счетчик цикла
	mov	AH,0Ch; (19)  функция вывода пикселя
	mov	AL,6; (20) установка цвета
	mov	BH,0; (21)  видеостраница
	mov	CX,SI; (22)  установка X-координаты
	int	10h; (23)  вызов BIOS
	inc	SI; (24)  счетчик Х-координаты
	pop	CX; (25)   выгрузим из стека счетчик цикла
	loop	h; (26)  уменьшим его на единицу
ret; (27)  выход из подпрограммы
horizontal	endp; (28)   конец текста подпрограммы

begin:	;(29)  начало основной программы
  mov	AX,00h; (30)  функция задания режима
	mov	AL,10h; (31)  графический режим EGA
	int	10h; (32)   вызов BIOS
mov cx,3
rect:	push cx
	mov	SI,100; (33)  Х-координата
	add si,i
	mov	DX,100; (34)  Y-координата
	add dx,i
	mov	CX,20; (35)  длина стороны
	call	vertical; (36)  вызов подпрограммы
	mov	SI,100; (37)  Х-координата
	add si,i
	mov	DX,100; (38) Y-координата
	add dx,i
	mov	CX,20; (39)  длина стороны
	call	horizontal; (40)  вызов подпрограммы
	
	mov	SI,120; (33)  Х-координата
	add si,i
	mov	DX,100; (34)  Y-координата
	add dx,i
	mov	CX,20; (35)  длина стороны
	call	vertical; (36)  вызов подпрограммы
	
	mov	SI,100; (37)  Х-координата
	add si,i
	mov	DX,120; (38) Y-координата
	add dx,i
	mov	CX,21; (39)  длина стороны
	call	horizontal; (40)  вызов подпрограммы
add i,22
pop cx
loop rect	
	
	mov AH,08h
	int 21h
	
	mov AH,00h
	mov AL,03h
	int 10h
	
	mov	AX,4C00h; (41)  завершение программы
	int	21h; (42)
text	ends; (43)   конец сегмента команд

data segment
i dw 0
data ends

stk segment stack
	dw 128 dup (0)
stk ends

end  	begin; (44)  конец текста программы




Хотела получить рядом расположенные квадратики..но как я предполагаю содержимое регистра СХ сбивается..
Как исправить - не пойму..

Сообщение отредактировано: 18192123 -


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


У тебя в начале программы не инициализируется DS и i хранится черт знает где (в PSP). Добавь его инициализацию:
begin:
    mov ax,data
    mov ds,ax


Сообщение отредактировано: xds -


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Добавила перерисовку квадратов по нажатию соответствующей цифровой клавиши (пока только 1-го и 2-го из них) - т.е так мы активируем квадрат для последующего управления. Но не получается стирать ранее нарисованные - не могу "поймать" ту же позицию, чтоб перерисовать чёрным цветом..Та же проблема и с изменением цвета ранее нарисованного квадрата (переход на метку color)..

И самое непонятное - не могу организовать управление квадратами, чтоб получить фигурки..не пойму ,как это сделать наиболее рационально...Подкиньте пожалуста идеи..Объясните, как поступить..


text	segment 'code' ; (1)  начало сегмента команд
              assume CS:text,DS:data; (2)
vertical	proc; (3)  объявление процедуры построения вертикальной линии
v:	; (4)    
	push	CX; (5)   сохраним в стек счетчик цикла
	mov	AH,0Ch; (6)  функция вывода пикселя
	;mov	AL,15; (7)  установка цвета
	mov	BH,0; (8)  видеостраница
	mov	CX,SI; (9)  установка X-координаты
	int	10h; (10)  вызов BIOS
	inc	DX; (11)  счетчик Y-координаты 
	pop	CX; (12)  выгрузим из стека счетчик цикла
	loop	v; (13)  уменьшим его на единицу
ret; (14)  выход из подпрограммы
vertical	endp; (15)  конец текста подпрограммы
horizontal	proc; (16)  объявление процедуры построения горизонтальной линии
h:	; (17)
	push	CX; (18)  сохраним в стек счетчик цикла
	mov	AH,0Ch; (19)  функция вывода пикселя
	;mov	AL,15; (20) установка цвета
	mov	BH,0; (21)  видеостраница
	mov	CX,SI; (22)  установка X-координаты
	int	10h; (23)  вызов BIOS
	inc	SI; (24)  счетчик Х-координаты
	pop	CX; (25)   выгрузим из стека счетчик цикла
	loop	h; (26)  уменьшим его на единицу
ret; (27)  выход из подпрограммы
horizontal	endp; (28)   конец текста подпрограммы

rectangle proc
push cx
	mov	SI,10; (33)  Х-координата
	add SI,j
	mov	DX,10; (34)  Y-координата
	add dx,i
	mov	CX,20; (35)  длина стороны
	call	vertical; (36)  вызов подпрограммы
	mov	SI,10; (37)  Х-координата
	add SI,j
	mov	DX,10; (38) Y-координата
	add dx,i
	mov	CX,20; (39)  длина стороны
	call	horizontal; (40)  вызов подпрограммы
	
	mov	SI,30; (33)  Х-координата
	add SI,j
	mov	DX,10; (34)  Y-координата
	add dx,i
	mov	CX,20; (35)  длина стороны
	call	vertical; (36)  вызов подпрограммы
	
	mov	SI,10; (37)  Х-координата
	add SI,j
	mov	DX,30; (38) Y-координата
	add dx,i
	mov	CX,21; (39)  длина стороны
	call	horizontal; (40)  вызов подпрограммы
add i,30
pop cx
ret
rectangle endp

begin:	;(29)  начало основной программы
	mov ax,data
    mov ds,ax

	mov	AX,00h; (30)  функция задания режима
	mov	AL,10h; (31)  графический режим EGA
	int	10h; (32)   вызов BIOS
	mov cx,9

rect:
		mov AL,15
		call rectangle
loop rect	
	
cikl:
	mov AH,08h
	int 21h
	cmp AL,31h
	je one
	cmp AL,32h
	je two
	cmp AL,32
	je color
	cmp AL,44h
	je exit
	jmp cikl
one:
	mov i,0
	add j,30
	mov AL,15
	call rectangle
	jmp cikl
two:
	mov i,30
	add j,30
	mov AL,15
	call rectangle
	jmp cikl
color:
	mov AL,12
	call rectangle
	jmp cikl
exit:
    mov AH,00h
	mov AL,03h
	int 10h
	
	mov	AX,4C00h; (41)  завершение программы
	int	21h; (42)

text	ends; (43)   конец сегмента команд

data segment
i dw 0
j dw 0
data ends

stk segment stack
	dw 128 dup (0)
stk ends

end  	begin; (44)  конец текста программы


 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Я бы использовал видеорежим с линейным буфером и вывод прямой записью в видеопамять. Тогда стирание старого изображения квадрата можно реализовать с помощью операции "исключающее ИЛИ", что упростит вывод нескольких квадратов с их перемещением. Примерно вот так:
BOX_SIZE	equ 20		;длина стороны квадрата
SCR_WIDTH	equ 320		;ширина экрана

locals

.model small

.stack 2048

.data

;координаты и цвет квадрата
x		dw 10
y		dw 20
color	db 1

.code

;----- вывод квадрата с заданными координатами и цветом -----
draw_box:
;вичисление смещения в видеобуфере по заданным координатам x и y
;bx = y * SCR_WIDTH + x
	mov ax,SCR_WIDTH
	mul y
	add ax,x
	mov bx,ax
	mov al,color
;вывод верхней стороны
	mov cx,BOX_SIZE-1
@@1:
	xor es:[bx],al
	inc bx
	loop @@1
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@2:
	xor es:[bx],al
	add bx,SCR_WIDTH
	loop @@2
;вывод нижней стороны
	mov cx,BOX_SIZE-1
@@3:
	xor es:[bx],al
	dec bx
	loop @@3
;вывод левой стороны
	mov cx,BOX_SIZE-1
@@4:
	xor es:[bx],al
	sub bx,SCR_WIDTH
	loop @@4
	ret

;----- основная программа -----
entry:
;инициализация ds
	mov ax,@data
	mov ds,ax

;запомнить в стеке номер текущего видеорежима
	mov ah,0Fh
	int 10h
	push ax
;установка видеорежима 320x200x256
	mov ax,13h
	int 10h

;es:0 -> видеобуфер
	mov ax,0A000h
	mov es,ax

;вывод неподвижного квадрата
	call draw_box

;начальные координаты и цвет перемещаемого квадрата
	mov x,0
	mov y,0
	mov color,2

redraw:
;вывести квадрат
	call draw_box

;ожидать нажатия клавиши
	xor ax,ax
	int 16h
;выход по ESC
	cmp al,27
	je exit

;стереть квадрат
	call draw_box

;вычислить новые координаты
	add x,2
	inc y

	jmp redraw

exit:
;восстановить видеорежим
	pop ax
	xor ah,ah
	int 10h

;выход
	mov ax,4C00h
	int 21h

end entry


Сообщение отредактировано: xds -


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(xds @ 19.04.2008 17:05) *

Я бы использовал видеорежим с линейным буфером и вывод прямой записью в видеопамять. Тогда стирание старого изображения квадрата можно реализовать с помощью операции "исключающее ИЛИ", что упростит вывод нескольких квадратов с их перемещением.


Спасибо большое..Так намного эффективнее..
У меня возникли ещё вопросы...
А как сделать, чтоб можно двигать несколько квадратов: подвинули один..потом второй..и так сколько нужно..?
Я попыталась - неудачно..

BOX_SIZE	equ 20		;длина стороны квадрата
SCR_WIDTH	equ 320		;ширина экрана

locals

.model small

.stack 2048

.data

;координаты и цвет квадрата
x		dw 0
y		dw 0
color	db 1

.code

;----- вывод квадрата с заданными координатами и цветом -----
draw_box:
;вичисление смещения в видеобуфере по заданным координатам x и y
;bx = y * SCR_WIDTH + x
	mov ax,SCR_WIDTH
	mul y
	add ax,x
	mov bx,ax
	mov al,color
;вывод верхней стороны
	mov cx,BOX_SIZE-1
@@1:
	xor es:[bx],al
	inc bx
	loop @@1
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@2:
	xor es:[bx],al
	add bx,SCR_WIDTH
	loop @@2
;вывод нижней стороны
	mov cx,BOX_SIZE-1
@@3:
	xor es:[bx],al
	dec bx
	loop @@3
;вывод левой стороны
	mov cx,BOX_SIZE-1
@@4:
	xor es:[bx],al
	sub bx,SCR_WIDTH
	loop @@4
	ret

;----- основная программа -----
entry:
;инициализация ds
	mov ax,@data
	mov ds,ax

;запомнить в стеке номер текущего видеорежима
	mov ah,0Fh
	int 10h
	push ax
;установка видеорежима 320x200x256
	mov ax,13h
	int 10h

;es:0 -> видеобуфер
	mov ax,0A000h
	mov es,ax

;вывод неподвижного квадрата
	mov cx,9
rect:
	push cx
	call draw_box
	add y,25
	pop cx
loop rect
;начальные координаты и цвет перемещаемого квадрата
	xor ax,ax
	int 16h
check:	;проверяем какая клавишка нажата
	cmp al,31h ;если 1 - то двигать 1-й квадрат
	je one
	cmp al,32h ;если 2 - то второй...
	je two
	cmp al,27
	je exit

one:
	mov x,0
	mov y,25
	mov color,2
	jmp redraw
two:
	mov x,0
	mov y,50
	mov color,2

redraw:
;вывести квадрат
	call draw_box

;ожидать нажатия клавиши
	xor ax,ax
	int 16h
;выход по ESC
	cmp al,27
	je exit

;стереть квадрат
	call draw_box

;вычислить новые координаты
	add x,2
	inc y

	jmp redraw

exit:
;восстановить видеорежим
	pop ax
	xor ah,ah
	int 10h

;выход
	mov ax,4C00h
	int 21h

end entry



 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Имеет смысл работать с квадратами, как со структурами (зачатки ООП). Текущий квадрат представляется в виде указателя на его структуру (в данном случае это регистр si):
BOX_SIZE	equ 20		;длина стороны квадрата
SCR_WIDTH	equ 320		;ширина экрана

locals

.model small

.stack 2048

.data

;----- структура-квадрат (описание типа) -----
box		struc
x		dw ?
y		dw ?
color	db ?
box		ends

;----- список квадратов (переменные) -----
box1	box <20, 20, 1>
box2	box <0, 0, 2>

.code

;----- вывод квадрата с заданными координатами и цветом -----
draw_box:
;вичисление смещения в видеобуфере по заданным координатам x и y
;bx = y * SCR_WIDTH + x
	mov ax,SCR_WIDTH
	mul [si].y
	add ax,[si].x
	mov bx,ax
	mov al,[si].color
;вывод верхней стороны
	mov cx,BOX_SIZE-1
@@1:
	xor es:[bx],al
	inc bx
	loop @@1
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@2:
	xor es:[bx],al
	add bx,SCR_WIDTH
	loop @@2
;вывод нижней стороны
	mov cx,BOX_SIZE-1
@@3:
	xor es:[bx],al
	dec bx
	loop @@3
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@4:
	xor es:[bx],al
	sub bx,SCR_WIDTH
	loop @@4
	ret

;----- основная программа -----
entry:
;инициализация ds
	mov ax,@data
	mov ds,ax

;запомнить в стеке номер текущего видеорежима
	mov ah,0Fh
	int 10h
	push ax
;установка видеорежима 320x200x256
	mov ax,13h
	int 10h

;es:0 -> видеобуфер
	mov ax,0A000h
	mov es,ax

;выбрать первый квадрат
	lea si,box1
;вывести его
	call draw_box

;выбрать второй квадрат
	lea si,box2

redraw:
;вывести текущий квадрат
	call draw_box

;ожидать нажатия клавиши
	xor ax,ax
	int 16h
;выход по ESC
	cmp al,27
	je exit

;стереть текущий квадрат
	call draw_box

;вычислить новые координаты текущего
	add [si].x,2
	inc [si].y

	jmp redraw

exit:
;восстановить видеорежим
	pop ax
	xor ah,ah
	int 10h

;выход
	mov ax,4C00h
	int 21h

end entry


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(xds @ 20.04.2008 20:21) *

Имеет смысл работать с квадратами, как со структурами (зачатки ООП). Текущий квадрат представляется в виде указателя на его структуру (в данном случае это регистр si):


А если без структур и указателей? Просто нам этого не объясняли..
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Структур как таковых в ассемблере нет на самом деле. Запись
box		struc
x		dw ?
y		dw ?
color	db ?
box		ends
эквивалентна
x equ word ptr[0]
y equ word ptr [2]
color equ byte ptr [4]


а, mov al,[si].color - на самом деле это mov al,[si+4]. Т. е., si хранит адрес начала области памяти, в которой последовательно хранятся координата x (как word), координата y (как word) и цвет (как байт

Вот эквивалентный вариант без конструкции struc:
BOX_SIZE	equ 20		;длина стороны квадрата
SCR_WIDTH	equ 320		;ширина экрана

locals

.model small

.stack 2048

.data

;----- структура-квадрат (описание типа) -----
x		equ word ptr [0]
y		equ word ptr [2]
color	equ byte ptr [4]

;----- список квадратов (переменные) -----
box1	dw 20
		dw 20
		db 1

box2	dw 0
		dw 0
		db 2

.code

;----- вывод квадрата с заданными координатами и цветом -----
draw_box:
;вичисление смещения в видеобуфере по заданным координатам x и y
;bx = y * SCR_WIDTH + x
	mov ax,SCR_WIDTH
	mul [si].y
	add ax,[si].x
	mov bx,ax
	mov al,[si].color
;вывод верхней стороны
	mov cx,BOX_SIZE-1
@@1:
	xor es:[bx],al
	inc bx
	loop @@1
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@2:
	xor es:[bx],al
	add bx,SCR_WIDTH
	loop @@2
;вывод нижней стороны
	mov cx,BOX_SIZE-1
@@3:
	xor es:[bx],al
	dec bx
	loop @@3
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@4:
	xor es:[bx],al
	sub bx,SCR_WIDTH
	loop @@4
	ret

;----- основная программа -----
entry:
;инициализация ds
	mov ax,@data
	mov ds,ax

;запомнить в стеке номер текущего видеорежима
	mov ah,0Fh
	int 10h
	push ax
;установка видеорежима 320x200x256
	mov ax,13h
	int 10h

;es:0 -> видеобуфер
	mov ax,0A000h
	mov es,ax

;выбрать первый квадрат
	lea si,box1
;вывести его
	call draw_box

;выбрать второй квадрат
	lea si,box2

redraw:
;вывести текущий квадрат
	call draw_box

;ожидать нажатия клавиши
	xor ax,ax
	int 16h
;выход по ESC
	cmp al,27
	je exit

;стереть текущий квадрат
	call draw_box

;вычислить новые координаты текущего
	add [si].x,2
	inc [si].y

	jmp redraw

exit:
;восстановить видеорежим
	pop ax
	xor ah,ah
	int 10h

;выход
	mov ax,4C00h
	int 21h

end entry


По другому мне прямо сейчас лень - там больше писанины и меньше разумности.


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


И снова здраствуйте)

Я добавила переменные box3,..,box9. Осуществила их вывод. По нажатию соответствующей цифровой клавиши 1-й, 2-й или i-й квадрат должен свигаться со своей позиции и изменять положение...Вот только у меня всегда сдвигается 1-й квадрат..Объясните пожалуста, в чём дело?



BOX_SIZE	equ 15		;длина стороны квадрата
SCR_WIDTH	equ 320		;ширина экрана

locals

.model small

.stack 2048

.data

;----- структура-квадрат (описание типа) -----
x		equ word ptr [0]
y		equ word ptr [2]
color	equ byte ptr [4]

;----- список квадратов (переменные) -----
box1	dw 0
		dw 10
		db 1

box2	dw 20
		dw 10
		db 2
box3	dw 40
		dw 10
		db 2
box4	dw 60
		dw 10
		db 2
box5	dw 80
		dw 10
		db 2
box6	dw 100
		dw 10
		db 2

box7	dw 120
		dw 10
		db 2

box8	dw 140
		dw 10
		db 2

box9	dw 160
		dw 10
		db 2

.code

;----- вывод квадрата с заданными координатами и цветом -----
draw_box:
;вичисление смещения в видеобуфере по заданным координатам x и y
;bx = y * SCR_WIDTH + x
	mov ax,SCR_WIDTH
	mul [si].y
	add ax,[si].x
	mov bx,ax
	mov al,[si].color
;вывод верхней стороны
	mov cx,BOX_SIZE-1
@@1:
	xor es:[bx],al
	inc bx
	loop @@1
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@2:
	xor es:[bx],al
	add bx,SCR_WIDTH
	loop @@2
;вывод нижней стороны
	mov cx,BOX_SIZE-1
@@3:
	xor es:[bx],al
	dec bx
	loop @@3
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@4:
	xor es:[bx],al
	sub bx,SCR_WIDTH
	loop @@4
	ret

;----- основная программа -----
entry:
;инициализация ds
	mov ax,@data
	mov ds,ax

;запомнить в стеке номер текущего видеорежима
	mov ah,0Fh
	int 10h
	push ax
;установка видеорежима 320x200x256
	mov ax,13h
	int 10h

;es:0 -> видеобуфер
	mov ax,0A000h
	mov es,ax

;выбрать первый квадрат
	lea si,box1
;вывести его
	call draw_box

	lea si,box2
	call draw_box
	lea si,box3
	call draw_box
	lea si,box4
	call draw_box
	lea si,box5
	call draw_box
	lea si,box6
	call draw_box
	lea si,box7
	call draw_box
	lea si,box8
	call draw_box
	lea si,box9
	call draw_box
	
	cmp AL,31h
	je one
	cmp AL,32h
	je two
	cmp AL,33h
	je three
	cmp AL,34h
	je four
	cmp AL,35h
	je five
	cmp AL,36h
	je six
	cmp AL,37h
	je seven
	cmp AL,38h
	je eigth
	cmp AL,39h
	je nine

one: lea si,box1
	jmp redraw
two: lea si,box2
	jmp redraw
three: lea si,box3
	jmp redraw
four: lea si,box4
	jmp redraw
five: lea si,box5
	jmp redraw
six: lea si,box6
	jmp redraw
seven: lea si,box7
	jmp redraw
eigth: lea si,box8
	jmp redraw
nine: lea si,box9

redraw:
;вывести текущий квадрат
	;call draw_box

;ожидать нажатия клавиши
	xor ax,ax
	int 16h
;выход по ESC
	cmp al,27
	je exit

;стереть текущий квадрат
	call draw_box

;вычислить новые координаты текущего
	add [si].x,2
	inc [si].y

	jmp redraw

exit:
;восстановить видеорежим
	pop ax
	xor ah,ah
	int 10h

;выход
	mov ax,4C00h
	int 21h

end entry


 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(xds @ 20.04.2008 21:40) *


BOX_SIZE	equ 20		;длина стороны квадрата
SCR_WIDTH	equ 320		;ширина экрана

locals

.model small

.stack 2048

.data

;----- структура-квадрат (описание типа) -----
x		equ word ptr [0]
y		equ word ptr [2]
color	equ byte ptr [4]

;----- список квадратов (переменные) -----
box1	dw 20
		dw 20
		db 1

box2	dw 0
		dw 0
		db 2

.code

;----- вывод квадрата с заданными координатами и цветом -----
draw_box:
;вичисление смещения в видеобуфере по заданным координатам x и y
;bx = y * SCR_WIDTH + x
	mov ax,SCR_WIDTH
	mul [si].y
	add ax,[si].x
	mov bx,ax
	mov al,[si].color
;вывод верхней стороны
	mov cx,BOX_SIZE-1
@@1:
	xor es:[bx],al
	inc bx
	loop @@1
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@2:
	xor es:[bx],al
	add bx,SCR_WIDTH
	loop @@2
;вывод нижней стороны
	mov cx,BOX_SIZE-1
@@3:
	xor es:[bx],al
	dec bx
	loop @@3
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@4:
	xor es:[bx],al
	sub bx,SCR_WIDTH
	loop @@4
	ret

;----- основная программа -----
entry:
;инициализация ds
	mov ax,@data
	mov ds,ax

;запомнить в стеке номер текущего видеорежима
	mov ah,0Fh
	int 10h
	push ax
;установка видеорежима 320x200x256
	mov ax,13h
	int 10h

;es:0 -> видеобуфер
	mov ax,0A000h
	mov es,ax

;выбрать первый квадрат
	lea si,box1
;вывести его
	call draw_box

;выбрать второй квадрат
	lea si,box2

redraw:
;вывести текущий квадрат
	call draw_box

;ожидать нажатия клавиши
	xor ax,ax
	int 16h
;выход по ESC
	cmp al,27
	je exit

;стереть текущий квадрат
	call draw_box

;вычислить новые координаты текущего
	add [si].x,2
	inc [si].y

	jmp redraw

exit:
;восстановить видеорежим
	pop ax
	xor ah,ah
	int 10h

;выход
	mov ax,4C00h
	int 21h

end entry




Объясните пожалуста, как на основании такого фрагмента осуществить изменение цвета активного квадратика по нажатию какой-нибудь клавиши?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


N337
****

Группа: Пользователи
Сообщений: 737
Пол: Мужской

Репутация: -  26  +


Клавиши "+" и "-" меняют цвет выбранного квадрата:
BOX_SIZE	equ 20		;длина стороны квадрата
SCR_WIDTH	equ 320		;ширина экрана

locals

.model small

.stack 2048

.data

;----- структура-квадрат (описание типа) -----
x		equ word ptr [0]
y		equ word ptr [2]
color	equ byte ptr [4]

;----- список квадратов (переменные) -----
boxes	dw 30
		dw 30
		db 1

		dw 40
		dw 40
		db 2
		
		dw 50
		dw 50
		db 3

		dw 60
		dw 60
		db 4
		
		dw 70
		dw 70
		db 5
		
		dw 80
		dw 80
		db 6
		
		dw 90
		dw 90
		db 7
		
		dw 100
		dw 100
		db 8
		
		dw 110
		dw 110
		db 9

.code

;----- вывод квадрата с заданными координатами и цветом -----
draw_box:
;вичисление смещения в видеобуфере по заданным координатам x и y
;bx = y * SCR_WIDTH + x
	mov ax,SCR_WIDTH
	mul [si].y
	add ax,[si].x
	mov bx,ax
	mov al,[si].color
;вывод верхней стороны
	mov cx,BOX_SIZE-1
@@1:
	xor es:[bx],al
	inc bx
	loop @@1
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@2:
	xor es:[bx],al
	add bx,SCR_WIDTH
	loop @@2
;вывод нижней стороны
	mov cx,BOX_SIZE-1
@@3:
	xor es:[bx],al
	dec bx
	loop @@3
;вывод правой стороны
	mov cx,BOX_SIZE-1
@@4:
	xor es:[bx],al
	sub bx,SCR_WIDTH
	loop @@4
	ret

;----- основная программа -----
entry:
;инициализация ds
	mov ax,@data
	mov ds,ax

;запомнить в стеке номер текущего видеорежима
	mov ah,0Fh
	int 10h
	push ax
;установка видеорежима 320x200x256
	mov ax,13h
	int 10h

;es:0 -> видеобуфер
	mov ax,0A000h
	mov es,ax

;для начала, вывести все квадраты
	lea si,boxes
	push si
	mov cx,9
init_box:
	push cx
	call draw_box
	add si,5
	pop cx
	loop init_box
	pop si

get_key:
;ожидать нажатия клавиши
	xor ax,ax
	int 16h
;выход по ESC
	cmp al,27
	je exit
;"+" - выбрать следующий цвет для текущего квадрата
	cmp al,'+'
	je inc_color
;"-" - выбрать предыдущий цвет для текущего квадрата
	cmp al,'-'
	je dec_color
;нажата ли клавиша с цифрой?
	cmp al,'1'
	jb non_digit
	cmp ah,'9'
	jbe sel_square
non_digit:
;нажата ли клавиша со стрелкой?
	cmp ax,4800h
	je up
	cmp ax,4B00h
	je left
	cmp ax,4D00h
	je right
	cmp ax,5000h
	je down
	jmp get_key

redraw:
;вывести текущий квадрат
	call draw_box
	jmp get_key

;выбор крадрата по нажатию клавиши с цифрой '1'-'9'
sel_square:
	sub al,'1'		;si = (al - '1') * 5
	mov ah,5
	mul ah
	lea si,boxes
	add si,ax
	jmp get_key

dec_color:
;стереть текущий квадрат
	cmp [si].color,1
	jbe redraw	
	call draw_box
	dec [si].color
	jmp redraw

inc_color:
;стереть текущий квадрат
	cmp [si].color,15
	jae redraw
	call draw_box
	inc [si].color
	jmp redraw

up:
;стереть текущий квадрат
	call draw_box
	dec [si].y
	jmp redraw

left:
;стереть текущий квадрат
	call draw_box
	dec [si].x
	jmp redraw

right:
;стереть текущий квадрат
	call draw_box
	inc [si].x
	jmp redraw

down:
;стереть текущий квадрат
	call draw_box
	inc [si].y
	jmp redraw

exit:
;восстановить видеорежим
	pop ax
	xor ah,ah
	int 10h

;выход
	mov ax,4C00h
	int 21h

end entry


--------------------
The idiots are winning.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






скажите а как этот код сделать рабочим для Pascal 7.1 со встроенным assembler?
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 12.01.2025 9:29
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name