Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Чемпионы рейтинга экспертов в этой рассылке Номер выпуска: | 1365 | Дата выхода: | 22.06.2010, 05:30 | Администратор рассылки: | Лысков Игорь Витальевич, Старший модератор | Подписчиков / экспертов: | 236 / 63 | Вопросов / ответов: | 2 / 2 | IRC-канал по теме: | #assembler | Вопрос № 179122: В приложении программа движущегося вертикально вниз отрезка. Помогите сделать, чтобы так же выводилась и двигалась маска размером, например, 3х5 байт. Msk db 01,04,01 01,04,01 01,04,01 01,04,01 Вопрос № 179128: Здравствуйте уважаемые эксперты! Помогите пожалуйста решить следующую задачу: Написать рекурсивную процедуру решения задачи о "Ханойской башне". Прошу подробные комментарии, т.к. в ассемблере не очень. Программа Tasm 5.0. Буду... Вопрос № 179122: В приложении программа движущегося вертикально вниз отрезка. Помогите сделать, чтобы так же выводилась и двигалась маска размером, например, 3х5 байт. Msk db 01,04,01 01,04,01 01,04,01 01,04,01 01,04,01 В режиме 13h я смог сделать движение маски, а в 12h не могу даже вывести на экран маску – у меня просто регистров почему-то не хватает. Отправлен: 16.06.2010, 08:31 Вопрос задал: Adsorores, Посетитель Всего ответов: 1 Страница вопроса » Отвечает amnick, Профессионал : Здравствуйте, Adsorores.
Вот, пожалуйста:
Код: locals @@ .model tiny, C
.code .startup
mov ax, 0012h ;графический режим 12h, vga 640х480х16 int 10h
mov dx, 03CEh ;индексный порт графического контроллера mov ax, 0F01h ;регистр 01h: разрешение установки/сброса out dx, ax
mov ax, 0a000h mov es, ax ; es - сегмент видео MainLoop: call Draw,offset msk ;адрес маски call DELAY ;задержка
mov ah,1 ;проверка на нажатие клавиши int 16h jz @@1 cmp al,' ' ; пробел - пауза, можно рассмотреть рисунок jne @@1 mov ah, 0 ;извлекаем код клавиши из буфера int 16h xor ax,ax ; ждем нажатия клавиши int 16h cmp ah, 1 ; по Esc выходим je Exit @@1: call Draw,offset black ;стираем add row,5 ;шаг движения call Proverka ;проверка на последнюю строку
mov ah,1 ;проверка на нажатие клавиши int 16h jz MainLoop mov ah, 0 ;извлекаем код клавиши из буфера int 16h cmp ax,4b00h ; влево jne @@2 dec [column] jmp MainLoop @@2: cmp ax,4d00h ; вправо jne @@3 inc [column] jmp MainLoop @@3: cmp ah, 1 ;по Esc выходим jne MainLoop Exit: mov ax, 0003h ;восстановим текстовый режим int 10h
mov ax, 4c00h int 21h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.286 Draw proc maska: word ; вычислить номер байта в видеопамяти mov ax, [row] ;AX = строка mov bx, 80 mul bx ;AХ = АХ * 80 = строка * байт_в_строке
mov di, ax ;сохранить адрес начала строки в di mov ax, [column] mov cl, al shr ax, 3 ;AX = номер байта в строке add di, ax ;DI = номер байта в видеопамяти and cl, 7 ;вычислить номер бита в байте, остаток от ; деления на 8 – номер бита в байте mov ch, 80h shr ch, cl ;нужный бит установлен в 1 mov dx, 03CEh ;индексный порт графического контроллера
mov si,[maska] mov bl,[si] ; число строк inc si mov cl,[si] ; число столбцов inc si @@next_row: push di ; сохраняем смещение начала маски в видеобуфере push cx ; маска пикселя и число столбцов
@@next_pixel: mov ah, [si] ;цвет mov al, 0 ;al = регистр установки/сброса out dx, ax ;ah = цвет
mov al, 8 ; al = битовая маска mov ah, ch ;записать в битовую маску нули всюду, кроме out dx, ax ;бита, соответствующего выводимому пикселю
xchg es:[di],ah ;заполнить регистры-защелки и вывести на экран пиксель
inc si ; к следующему байту маски ror ch,1 ; маска для следующего пикселя jnc @@ 2 inc di ; к следующему байту видеобуфера @@2: dec cl jnz @@next_pixel pop cx ; восстанавливаем маску pop di add di,80 ; к следующей строке dec bl jnz @@next_row ret Draw endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; time equ 30 ;число интервалов по 10мс DELAY: ; pusha ;сохраним все регистры mov ah,2dh ;сбросим время xor cx,cx xor dx,dx int 21h
dl2: mov ah,2ch ; читаем время, GET SYSTEM TIME int 21h ; Return: CH = hour, CL = minute, DH = second, DL = 1/100 seconds ;считаем сотни мс mov al,100 mul dh ;секунды умножаем на 100 - ax = количество интервалов по 10мс xor dh,dh ;dx - число сотых xchg ax,dx ;поменяем местами mov cl,10 div cl ;ax = количество интервалов по 10мс из сотых add ax,dx ;складываем с количеством из секунд cmp ax,time ;сравним с ожидаемым интервалом jl dl2 ;ждем, если меньше ; popa ;восстановим все регистры ret
;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Proverka proc cmp row,470 ;доходим почти до края экрана, обнуляем строку. Если сравнить с 479, то ;верхний следующий пунктир выведется не с 320 колонки, а больше. jb @@1 mov row,0 @@1: cmp [column],630 jb @@2 mov [column],1 @@2: cmp [column],0 ja @@3 mov [column],629 @@3: ret Proverka endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.data
column dw 320 row dw 0 Msk db 10, 7 ; размер маски в точках: строк, столбцов db 8,8,8,8,8,8,8 db 8,1,1,14,1,1,8 db 8,1,1,14,1,1,8 db 8,1,1,14,1,1,8 db 8,1,1,14,1,1,8 db 8,1,1,14,1,1,8 db 8,14,14,14,14,14,8 db 8,1,14,14,14,1,8 db 8,1,1,14,1,1,8 db 8,8,8,8,8,8,8
black db 10, 7 ; размер маски в точках: строк, столбцов db 0,0,0,0,0,0,0 db 0,0,0,0,0,0,0 db 0,0,0,0,0,0,0 db 0,0,0,0,0,0,0 db 0,0,0,0,0,0,0 db 0,0,0,0,0,0,0 db 0,0,0,0,0,0, 0 db 0,0,0,0,0,0,0 db 0,0,0,0,0,0,0 db 0,0,0,0,0,0,0 END Дополнительно, я добавил возможность смещения выводимого шаблона вправо-влево по нажатию соответствующих стрелок (для проверки корректности функции отрисовки при переходе через границу байта) и паузу по пробелу (чтобы можно было спокойно рассмотреть рисунок на экране). В процедуре Draw вычисления вынесены за пределы цикла.
Ваша программа построена таким образом, что сохранение/восстановление регистров в процедурах не требуется, поэтому я удалил или закомментировал pusha/popa.
Успехов! Ответ отправил: amnick, Профессионал Ответ отправлен: 16.06.2010, 15:54 Номер ответа: 262145 Оценка ответа: 5 Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 262145 на номер 1151 (Россия) | Еще номера » | Вопрос № 179128: Здравствуйте уважаемые эксперты! Помогите пожалуйста решить следующую задачу:
Написать рекурсивную процедуру решения задачи о "Ханойской башне".
Прошу подробные комментарии, т.к. в ассемблере не очень. Программа Tasm 5.0. Буду очень благодарен!
Отправлен: 16.06.2010, 17:35 Вопрос задал: Петров Юрий Иванович, Посетитель Всего ответов: 1 Страница вопроса » Отвечает amnick, Профессионал : Здравствуйте, Петров Юрий Иванович.
Теорию можно почитать, например, здесь. Решение на ассемблере:
Код: .model tiny, pascal
N_RINGS = 4 ; число колец (до 9, иначе нужно менять вывод сообщения)
.data szInfo db 'Задача о "Ханойской башне" для ' db N_RINGS+'0',' колец.',13,10,'$' szMove db "0 -> 0",13,10,'$' szExit db "Press any key to exit...$"
.code .startup .286
; вывод информационного сообщения mov ah,9 ; AH=9 - вывод строки на экран mov dx,offset szInfo ; DS:DX = адр ес выводимой строки int 21h
mov al,N_RINGS ; начальное кол-во колец call hanoi_towers, 1, 3, 2
mov ah,9 ; AH=9 - вывод строки на экран mov dx,offset szExit ; DS:DX = адрес выводимой строки int 21h
xor ax,ax ; ждем нажатия клавиши int 16h
int 20h ; завершение программы (только .COM)
;--------------------------------------------------- ; AL = число колец ; from - начальное положение колец (1-3), ; to - конечное положение колец (1-3) ; temp - промежуточный колышек (1-3) ;--------------------------------------------------- hanoi_towers proc from: word, to: word, temp: word test al,al ; число колец = 0? jz @@ret
dec ax ; вызываем для числа колец на 1 меньше push ax ; сохраняем для второго вызова call hanoi_towers, from, temp, to
; формируем сообщение mov al,byte ptr [from] add al,'0' ; номер колышка - в символ mov [szMove],al mov al,byte ptr [to ] add al,'0' ; номер колышка - в символ mov [szMove+5],al mov ah,9 ; вывод строки на экран mov dx,offset szMove ; DS:DX = адрес выводимой строки int 21h
pop ax ; восстанавливаем число колец call hanoi_towers, temp, to, from @@ret: ret hanoi_towers endp
end
Успехов! Ответ отправил: amnick, Профессионал Ответ отправлен: 16.06.2010, 18:38 Номер ответа: 262147 Оценка ответа: 5 Комментарий к оценке: Прога работает, спасибо) Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 262147 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий