Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler
Регистрация

Восстановить пароль
Повторная активизация e-mail


Ответ
 
Опции темы
Старый 26.12.2017, 19:22   #1
marysluva
Пользователь
 
Регистрация: 18.12.2016
Сообщений: 29
Репутация: -2
По умолчанию Написать с использованием циклов программу на Ассемблере для рисования прямоугольника заданного размера в месте экрана, заданного координатами левой верхней вершины при помощи мишк

Какие ошибки?
Код:

LOCALS  @@
 
.model small
 
.stack 100h
 
.data
        ;коды клавиш
        KeyCode_Esc                     equ     1Bh     ;Esc
 
        ;Константы событий "мыши"
        MouseEvent_None                 equ     0000h   ;Удалить пользовательский обработчик
        MouseEvent_Move                 equ     0001h   ;любое перемещение
        MouseEvent_PressLeftButton      equ     0002h   ;нажатие левой кнопки
        MouseEvent_ReleaseLeftButton    equ     0004h   ;отпускание левой кнопки
        MouseEvent_PressRightButton     equ     0008h   ;нажатие правой кнопки
        MouseEvent_ReleaseRightButton   equ     0010h   ;отпускание правой кнопки
        MouseEvent_PressMiddleButton    equ     0020h   ;нажатие средней кнопки
        MouseEvent_ReleaseMiddleButton  equ     0040h   ;отпускание средней кнопки
 
        MouseInitOk                     equ     0FFFFh  ;инициализация мыши - успешна
        MouseInitFault                  equ     0000h   ;инициализация мыши - мышь или драйвер мыши не установлены
 
        MouseButtons_Any                equ     0000h   ;количество кнопок у мыши - отлично от 2 и 3
        MouseButtons_2                  equ     0002h   ;количество кнопок у мыши - 2
        MouseButtons_2_                 equ     0FFFFh  ;количество кнопок у мыши - 2
        MouseButtons_3                  equ     0003h   ;количество кнопок у мыши - 3
 
        ;Параметры курсоров мыши
        ;Курсор - перекрестие
        MouseCursor_Cross               dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh  ;screen mask (AND mask)
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      00100h, 00100h, 00100h, 00000h  ;cursor mask (XOR mask)
                                        dw      00100h, 00100h, 00000h, 0ED6Eh
                                        dw      00000h, 00100h, 00100h, 00000h
                                        dw      00100h, 00100h, 00100h, 00000h
                                        dw      7                               ;column of cursor hot spot in bitmap (-16 to 16)
                                        dw      7                               ;row of cursor hot spot (-16 to 16)
        ;Курсор - стрелка
        MouseCursor_Arrow               dw      03FFFh, 01FFFh, 00FFFh, 007FFh  ;screen mask (AND mask)
                                        dw      003FFh, 001FFh, 000FFh, 0007Fh
                                        dw      0003Fh, 001FFh, 020FFh, 0707Fh
                                        dw      0F03Fh, 0F83Fh, 0FC3Fh, 0FE7Fh
                                        dw      00000h, 04000h, 06000h, 07000h  ;cursor mask (XOR mask)
                                        dw      07800h, 07C00h, 07E00h, 07F00h
                                        dw      07800h, 04800,  00C00h, 00600h
                                        dw      00700h, 00380h, 00180h, 00000h
                                        dw      0                               ;column of cursor hot spot in bitmap (-16 to 16)
                                        dw      0                               ;row of cursor hot spot (-16 to 16)
        ;Курсор - прямоугольник
        MouseCursor_Rectangle           dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh  ;screen mask (AND mask)
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      0FFFFh, 0FFFFh, 0FFFFh, 0FFFFh
                                        dw      00000h, 00000h, 03FFCh, 02004h  ;cursor mask (XOR mask)
                                        dw      02004h, 02004h, 02004h, 02004h
                                        dw      02004h, 02004h, 02004h, 02004h
                                        dw      02004h, 03FFCh, 00000h, 00000h
                                        dw      7                               ;column of cursor hot spot in bitmap (-16 to 16)
                                        dw      7                               ;row of cursor hot spot (-16 to 16)
        ;признак готовности к рисованию прямоугольника
        Ready                           dw      0
        ;координаты левого верхнего угла прямоугольника
        Xstart                          dw      0
        Ystart                          dw      0
        ;размеры прямоугольника
        RectWidth                       dw      80
        RectHeigth                      dw      10
        ;цвет прямоугольника
        RectColor                       dw      7
        ;сообщения программы
        msgMouseFault                   db      'The mouse or mouse driver was not detected.', 13, 10, '$'
 
.code
 
;Ожидание нажатия клавиши на клавиатуре
;вход
; - нет
;выход
;ax - al - ASCII код нажатой клавиши, ah - скан-код
ReadKey         proc
        mov     ah,     00h
        int     16h
        ret
ReadKey         endp
 
;Инициализация работы с "мышью"
;Выполняется аппаратный и программный сброс мыши и драйвера
;вход
; - нет
;выход
;ax - результат инициализации
;   - 0000h, если мышь или драйвер мыши не установлены
;   - FFFFh, если драйвер и мышь установлены
;bx - число кнопок
;   - 0002 или FFFF - две
;   - 0003 - три
;   - 0000 - другое количество
MouseInit       proc
        mov     ax,     0000h
        int     33h
        ret
MouseInit       endp
 
;Показать курсор "мыши"
;вход
; - нет
;выход
; - нет
MouseShowCursor proc
        push    ax
        mov     ax,     0001h
        int     33h
        pop     ax
        ret
MouseShowCursor endp
 
;Спрятать курсор "мыши"
;вход
; - нет
;выход
; - нет
MouseHideCursor proc
        push    ax
        mov     ax,     0002h
        int     33h
        pop     ax
        ret
MouseHideCursor endp
 
;Определение курсора мыши в графическом режиме
;вход
;BX = column of cursor hot spot in bitmap (-16 to 16)
;CX = row of cursor hot spot (-16 to 16)
;ES:DX -> mask bitmap
;Format of mouse mask bitmap:
;Offset Size            Description
;00h    16 WORDs        screen mask
;10h    16 WORDs        cursor mask
;Note: Each word defines the sixteen pixels of a row, low bit rightmost
;выход
; - нет
MouseDefineGraphicsCursor       proc
        push    ax
        mov     ax,     0009h
        int     33h
        pop     ax
        ret
MouseDefineGraphicsCursor       endp
 
;Определение курсора мыши в текстовом режиме
;вход
;BX = hardware/software text cursor
;     0000h software ( (char/attr AND CX) XOR DX)
;       CX = screen mask
;       DX = cursor mask
;     0001h hardware
;       CX = start scan line
;       DX = end scan line
;выход
; - нет
MouseDefineTextCursor   proc
        push    ax
        mov     ax,     000Ah
        int     33h
        pop     ax
        ret
MouseDefineTextCursor   endp

marysluva вне форума   Ответить с цитированием
Старый 26.12.2017, 19:23   #2
marysluva
Пользователь
 
Регистрация: 18.12.2016
Сообщений: 29
Репутация: -2
По умолчанию

Код:

;Установить/удалить обработчик событий от "мыши"
;вход
;ES:DX = адрес обработчика
;СХ = условие вызова
;   бит 0 — любое перемещение мыши
;   бит 1 — нажатие левой кнопки
;   бит 2 — отпускание левой кнопки
;   бит 3 — нажатие правой кнопки
;   бит 4 — отпускание правой кнопки
;   бит 5 — нажатие средней кнопки
;   бит 6 — отпускание средней кнопки
;СХ = 0000h — отменить обработчик;выход
;выход
; - нет
MouseSetHandler proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    es
 
        mov     ax,     000Ch
        int     33h
 
        pop     es
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret
MouseSetHandler endp
 
;Обработчик событий "мыши"
;вход
;АХ содержит условие вызова,
;ВХ - состояние кнопок,
;СХ, DX - X- и Y-координаты курсора,
;SI, DI - счетчики последнего перемещения по горизонтали и вертикали
;      (единицы измерения для этих счетчиков - мики, 1/200 дюйма),
;DS - сегмент данных драйвера мыши.
;выход
; - нет
MyMouseHandler  proc
        push    ax
        push    bx
        push    cx
        push    dx
        push    si
        push    di
        push    es
 
        ;уточнение координат курсора
        shr     cx,     1       ;для графического видеорежима 13h нужно разделить на 2 координату X курсора
        ;сохранение координат левого верхнего угла прямоугольника
        mov     ax,     @data
        mov     es,     ax
        mov     es:[Xstart],    cx
        mov     es:[Ystart],    dx
        mov     es:[Ready],     1
@@Exit:
        pop     es
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        retf
MyMouseHandler  endp
 
;установить курсор - крест
MouseCursorCross        proc
        push    ax
        push    bx
        push    cx
        push    es
 
        mov     bx,     [MouseCursor_Cross+64]
        mov     cx,     [MouseCursor_Cross+66]
        mov     ax,     seg MouseCursor_Cross
        mov     es,     ax
        mov     dx,     offset [MouseCursor_Cross]
        call    MouseDefineGraphicsCursor
 
        pop     es
        pop     cx
        pop     bx
        pop     ax
        ret
MouseCursorCross        endp
 
;макрос для упрощения вызова процедур с параметрами
invoke  macro   CallProc, Params
        IRP     P, <Params>
                mov     ax,     P
                push    ax
        endm
        call    CallProc
endm
;рисование полосы (залитого прямоугольника)
;на входе:
; 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
 
;основная программа
main            proc
        mov     ax,     @data
        mov     ds,     ax
 
        ;попытка инициализации мыши
        call    MouseInit
        cmp     ax,     MouseInitOk
        je      @@MouseInitOk
        ;если инициализация не удалась - вывести сообщение
        ;и завершить программу
        mov     ah,     09h
        lea     dx,     msgMouseFault
        int     21h
        jmp     @@Exit
 
@@MouseInitOk:
        ;установить графический режим
        mov     ah,     00h
        mov     al,     13h
        int     10h
 
        ;установить курсор
        call    MouseCursorCross
        ;показать курсор
        call    MouseShowCursor
        ;установить пользовательский обработчик событий "мыши"
        push    es
        mov     ax,     seg MyMouseHandler
        mov     es,     ax
        mov     dx,     offset  MyMouseHandler
        mov     cx,     MouseEvent_ReleaseLeftButton
        call    MouseSetHandler
        pop     es
 
        ;цикл ожидания нажатия ЛКМ
@@WaitCoord:
        or      [Ready],        0
        jz      @@WaitCoord
 
        ;рисование прямоугольника
        call    MouseHideCursor
        invoke  Bar, <[RectHeigth], [RectWidth], [Ystart], [Xstart], [RectColor]>
        call    MouseShowCursor
        ;цикл ожидания нажатия кнопки ESC
@@WaitEscapePressed:
        call    ReadKey
        cmp     al,     KeyCode_Esc
        jne     @@WaitEscapePressed
 
        ;завершение работы с "мышью"
        ;спрятать курсор
        call    MouseHideCursor
        ;удалить пользовательский обработчик прерывания
        mov     cx,     MouseEvent_None
        call    MouseSetHandler
 
        ;установить текстовый режим
        mov     ah,     00h
        mov     al,     03h
        int     10h
 
@@Exit:
        mov     ax,     4C00h
        int     21h
main            endp
 
end     main

marysluva вне форума   Ответить с цитированием
Старый 26.12.2017, 21:40   #3
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 384
Репутация: 221
По умолчанию

Просто оставлю это здесь - http://www.cyberforum.ru/assembler-d...ad2161678.html

И выражу недоумение к топикстартеру по поводу появления данного поста.
FPaul вне форума   Ответить с цитированием
Старый 28.12.2017, 07:18   #4
R71MT
Профессионал
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,185
Репутация: 1014
По умолчанию

marysluva - это просто жесть какая-то!
70% кода можно смело отсеять в топку..
__________________
Нашедшего выход - затаптывают первым..
R71MT вне форума   Ответить с цитированием
Старый 28.12.2017, 10:13   #5
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 384
Репутация: 221
По умолчанию

R71MT - да, ладно?!

Процентов 10-20 за счёт удаления описания нескольких курсоров и неиспользуемых процедур - согласен.
Можно процедуры работы с мышью заменить макросами.

Но не более.

Смысл в процедурах (макросах) - именование действия, т.к. без этого придётся лезть в справочник. На быстродействие они не влияют, т.к. используются лишь при инициализации.

Но "модульность" влияет на скорость сбора итоговой программы из однотипных образцов.

Можно набрать этот же код без процедур (сокращение кучи push/pop, а с ними и десятки строк комментариев), но тогда main будет на несколько листов и смысл происходящего будет ускользать.

Да и лично я привык программировать "сверху-вниз": сначала набираю main с вызовами несуществующих процедур, потом по мере отладки заполняю процедуры.

Эту же задачу можно решить без прерываний - по опросу нажатия. Это сократит код, но мне не импонирует такое решение.
FPaul вне форума   Ответить с цитированием
Старый 28.12.2017, 12:46   #6
R71MT
Профессионал
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,185
Репутация: 1014
По умолчанию

Цитата:
Сообщение от FPaul Посмотреть сообщение
Процентов 10-20 - согласен. Можно процедуры работы с мышью заменить макросами. Смысл в процедурах (макросах) - именование действия, т.к. без этого придётся лезть в справочник. На быстродействие они не влияют, т.к. используются лишь при инициализации.
..да тут одни пуши пол кода занимают!
Зачем гонять данные в память и обратно, если в большинстве случаях они вообще не затрагиваются? Если уж сильно нужно, то проще записать их снова в регистр. Получается, что кто-то_когда-то сказал "сохранять все регистры перед входом в процедуру!", а зачем это нужно делать - объяснить забыл...

Процесс R/W-памяти занимает уйму времени: если проц тратит на 'попы' сегм\регистров по 3-такта, то память на 'пуши' аж 24-своих тактов. Вот и посчитай, сколько там этих попов.. На запись в память тратятся в 2 раза больше DRAM-тактов, чем на чтение. -хотя проц тратит наоборот - больше на чтение, чем на запись.

Вот и будет эта прога только писАть и читать память, вместо того, чтобы заниматься полезным делом. Я об этом говорю... Тут пуш'попится АХ, а на сл.шаге в этот-же АХ заносится новое значение.

На счёт задания вообще не понятно, что нужно делать - сменить курсор или нарисовать прямоугольник. Если рисовать, то почему координата только верхняя???
__________________
Нашедшего выход - затаптывают первым..
R71MT вне форума   Ответить с цитированием
Старый 28.12.2017, 20:16   #7
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 384
Репутация: 221
По умолчанию

А и вправду так долго или кэш процессора нивелирует?

Да даже если и так (долго), то на этапе обучения можно пренебречь скоростью выполнения процедур инициализации в пользу понятности кода. Не данный топикстартер, а какой нибудь другой разберётся с вызовами Mouse API и выполнит самостоятельно.
FPaul вне форума   Ответить с цитированием
Старый 28.12.2017, 20:23   #8
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 384
Репутация: 221
По умолчанию

Основная причина push/pop в том, что когда я разбирался с int 33h решил сделать на процедурах. Про макросы вспомнил позже, но переделывать не стал. А сейчас - на коренные изменения в шаблонных исходниках - нет времени. Может быть когда-нибудь (на том свете) отосплюсь, будет свободное время и оптимизирую код.
FPaul вне форума   Ответить с цитированием
Старый 28.12.2017, 21:37   #9
R71MT
Профессионал
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,185
Репутация: 1014
По умолчанию

Цитата:
Сообщение от FPaul Посмотреть сообщение
А и вправду так долго или кэш процессора нивелирует?
По сути, проц за пару-тройку обращений к памяти, поместит всю эту программу в свой кеш (т.к. читает память не байтами, а кеш-линейками по 64/128-байт - Intel/AMD). Данные отправятся в кеш-данных, а код - в кеш-инструкций. Но к сожалению, у ЦП нету кеша-стека! Любой пуш и поп отправляется прямиком в память - в этом и вся проблема.

Время операций R/W в память (в нс) сохранилось со-времён динозавров, поскольку здесь в игру вступают физические свойства конденсаторов динамической памяти, т.е. это время нельзя увеличить. Если раньше запись занимала в DRAM-тактах 25-30 (один пакетный цикл), то на новых типах памяти (DDR3) оно возросло до ~100 тактов. Расчитать его можно просуммировав тайминги памяти - на старых ОЗУ тайминги были ниже, сейчас выше. Процу по-барабану - он отправил запрос за свой такт, и занимается дальше своими делами. А дальше пыхтит уже сама память.

А на счёт кода никаких претензий нет - в нём нет ничего нового, и он как-правило статичен. Это я так... просто увидел много пушей... Ничего личного..
__________________
Нашедшего выход - затаптывают первым..
R71MT вне форума   Ответить с цитированием
Старый 28.12.2017, 21:46   #10
Pavia
Лис
Профессионал
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 1,525
Репутация: 1645
По умолчанию

R71MT
Не согласен с вашим утверждением. push pop так же кэшируются.
__________________
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Написать с использованием циклов программу на Ассемблере marysluva Assembler 1 20.12.2017 19:51
Попытка написать программу, которая для заданного числа i типа int const находит количество совпадающих единиц в старших 16 и младших 16 битах Son1098 Общие вопросы C/C++ 2 25.10.2016 11:35
С++ Написать программу, для вывода предложений, состоящих из заданного количества слов uropb992 Помощь студентам 0 28.05.2010 18:54
Написать программу которая для заданного символьного ряда подсчитывает количество слов! komarvl Assembler 4 11.12.2009 02:42


12:55.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru