Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

Boriss
Статус: Академик
Рейтинг: 2473
∙ повысить рейтинг »
_Ayl_
Статус: Профессионал
Рейтинг: 1901
∙ повысить рейтинг »
vladisslav
Статус: 6-й класс
Рейтинг: 1227
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И ПО / Программирование / Assembler (Ассемблер)

Номер выпуска: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 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Вопрос № 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 (Россия) | Еще номера »
  • Отправить WebMoney:

  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2010, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2010.6.16 от 26.05.2010

    В избранное