![]() |
![]() ![]() |
![]() |
Dark |
![]()
Сообщение
#1
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 408 Пол: Мужской Репутация: ![]() ![]() ![]() |
Се начнем повесть сию...
Итак, уважаемые, позвольте мне представить мой туториал №1. :D Он посвящен основам программирования графики на паскалевском ассемблере. Он предназначен для тех, кого достала тормознутость графики на пасе (а работать с графикой с его процедурами я бы не советовал - мееедленно...), кто хотел бы написать БЫСТРУЮ игру, да и для тех, кому вообще интересен асм. Внимание: Данные эксперименты не совсем совместимы с модулем Graph, поэтому крайне нежелательно его включать. Для использования примеров вам необходима карточка VGA, имеющая режим 320*200, TP версии 6.0 и выше, и желание разобраться. В сегодняшней, первой части, я расскажу о том, что из себя представляет режим 320*200 8 бит, как его врубить, и как с ним работать. Этот режим имеет номер 13 в шеснацатеричной системе счисления или 19 в десятичной. В дальнейшем 16-теричный вид будет отмечаться буквой h (Например 13h) а десятичный отмечатся не будет (19). Немного теории: Раз у нас 8-битный режим, то 1. На каждую ячейку(я.п.) памяти приходится по одной точке! Это просто чудесно! т.к. не рассматриваются случаи, когда в один байт картинки вмещается 2 точки (в 16ти цветных режимах), а то работа по разделению байта - просто геморой. 2.Мы можем работать с 2^8=256 цветами (в отличие от 16 в пасе)!!!!!!!!! 3. Базовый адрес памяти, начиная с которого изображение в графических режимах выводится на монитор, равен 0A000:0000h. следующие 64000(320*200) байта в данном режиме как раз и выводятся на экран. 5. Для возврата из графического режима я буду использовать текстовый режим № 3(80*25*16) Ну так вот, для того, чтобы менять режимы будем использовать функцию BIOS установки режима: ------------------------------------------------------------------------ Установка видеорежима(прерывание 10h): На входе: ah=0 ; Установить режим al = ; Номер режима ------------------------------------------------------------------------ В нашем случае:
Хорошо, вот мы и попали в режим 320*200*256 - возможно, скажете вы, - но Graph использовать не рекомендуют, так что же нам здесь делать? Ну... для начала давайте очистим экран
Итак, введя этот код вы получите процедуру закраски экрана. А теперь, давайте я пасскажу о ней поподробнее... Сегмент - это часть адреса, которая указывает от какой ячейки начинать отсчет смещения. Он имеет размер 64Кб (65536 байт). В языках программирования используют несколько переменных, которые содержат сегменты, это cs,ds,es,ss,gs,fs. В паскале реально используются лишь первые 4. cs - сегмент кода, обычно не трогается, ds - сегмент данных, здесь размещаются данные, после использования в паскале желательно восстанавливать. ss - сегмент стэка, в этом сегменте хранится то, что заносится в стек(в ручную или при вызове процедур). Стек - что-то типа временной памяти с последовательным доступом. es,fs,gs - дополнительные регистры, на 'всякий случай'. ;D Смещение - это вторая часть адреса, которая указывает на я.п. от начала сегмента. Принимает значения от 0 до 65535(по кол-ву байт в сегменте). Обычно, для адресации я.п. используют индексные регистры di и si, но можно использовать и любые другие. Сегмент и смещение занимают по 16 бит(2 байта) и преобразуются в 20-ти битный адрес. mov ax,0a000h Двумя этими командами мы помещаем в регистр es сегмент адреса видеопамяти(A000). Напрямую помещать адрес нельзя, т.е. запись типа mov es,0a000h является неверной!! По-моему это связано с отсутсвием кода команд в системе операций процессора. xor di,di Эта команда очищает регистр индекса di, для того, чтобы в es:di лежал полный адрес начала выводимой памяти... Индекс di используется для "скольжения" по сегменту, т.е. он адресует ячейку памяти с номером, указанную в нем. Внимание! Запись вида mov di,5 обозначает адресацию 5-ой ячейки, а запись вида mov [di],5 обозначает что в ячейку es:di будет помещено значение 5. Правда, в паскале это не так. В паскале для помещения значения 5 по адресу es:di оное значение помещается в регистр, допустим, аl и используется запись вида mov es:[di],al. mov al,[col] Здесь я помещаю в al номер цвета закраски фона. mov cx,64000 команда цикла rep повторяет следующую команду. количество повторов лежит в регистре CX. Ее можно заменить на команду цикла loop: @l1: Команда rep сначала проверяет регистр cx на равенство 0, а затем, если он не равен, убавляет его на 1, если равен, то цикл прекращается и программа идет дальше, в отличие от команды loop, которая сначала уменьшает cx на 1, а затем проверяет его на 0. Т.е. если вы поместите в cx 0, то команда rep не выполнится ни разу, а команда loop будет выполняться 65535 раз(по максимальному размеру cx) команда STOSB - es:[di]=al; di=di?1. Помещает содержимое al в я.п. по адресу es:di. В зависимости от df (флаг направления) уменьшает/увеличивает индекс di на 1. Если df = 0 то di увеличивается а если df=1, то di уменьшается. Поэтому я и указал в описании команды знак ?. Устанавливается df (df=1) командой std, а очищается - командой cld. Пример:
Happy codding!!!!!!!!!!!!! ;D З.Ы. Если вы хотите немного оптимизировать процедуру очистки экрана - то можете уменьшить значение счетчика в 2 раза и пересылать сразу по 2 байта: mov ah,al ;расширяю цвет... mov cx,32000 rep StosW команда StosW: es[di]=ax; di=di+2; З.Ы.Ы. Если вы хотите посмотреть, как будет выполнятся программа, можете ее прогнать пошагово, открыв окно Debug->Registers и нажимая F7. З.Ы.Ы.Ы. Просьба, если заметите неточности, или у вас есть предложения/просьбы/коментарии - высказывайте все либо на форуме http://forum.pascalnet.ru, либо лично мне по почте. Copyright by Dark. Моя почта: darkmaze@yandex.ru ;D -------------------- - Где я?
- Во тьме. - В какой тьме? - Во тьме твоего мозга. |
___ALex___ |
![]()
Сообщение
#2
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 282 Репутация: ![]() ![]() ![]() |
если уж ты пишешь туториал ты продумывай каждое своё слово
так как по этой "штуке" может кто-то вздумает учиться... и писать типа "Сегмент - это часть адреса, " - это полный бред сегмент - это непрерывный участок памяти размером в 64K (для Real Mode проца) а так продолжай писать... может кого асмом заинтересуешь ;) |
GLuk |
![]()
Сообщение
#3
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 775 Пол: Мужской Репутация: ![]() ![]() ![]() |
Полностью согласен с ___Alex___ по поводу сегмента. А вот остальные ошибки напишу позже. Похоже снова придется тебе переделывать...
![]() Второй раз уже круче, но ошибок больше. |
Dark |
![]()
Сообщение
#4
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 408 Пол: Мужской Репутация: ![]() ![]() ![]() |
Ок, давайте, выкристализовывайте, а на тему сегмента - все вопросы к моим преподам, ;D
А вот что я думаю: Сегмент и смещение ВМЕСТЕ составляют ЛОГИЧЕСКИЙ адрес, который в результате сдвига сегмента на 4 бита и сложения со смещением дает РЕАЛЬНЫЙ адрес объекта(20 бит)... Если я не прав - то поправте... А может есть 2 понятия слова сегмент? ;D ;D ;D -------------------- - Где я?
- Во тьме. - В какой тьме? - Во тьме твоего мозга. |
Dark |
![]()
Сообщение
#5
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 408 Пол: Мужской Репутация: ![]() ![]() ![]() |
Мне не сложно переписывать туториал столько раз, сколько это понадобится, главное, чтобы это не превратилось в манию ;D
А так, я всегда рад критике - если критикуют, то то, что я пишу комуто пригодится... -------------------- - Где я?
- Во тьме. - В какой тьме? - Во тьме твоего мозга. |
Dark |
![]()
Сообщение
#6
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 408 Пол: Мужской Репутация: ![]() ![]() ![]() |
Я тя понял... а унас в питере ГРОЗЫ, ;D Азачем напиватся с хорошей погоды ??? ;D
-------------------- - Где я?
- Во тьме. - В какой тьме? - Во тьме твоего мозга. |
GLuk |
![]()
Сообщение
#7
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 775 Пол: Мужской Репутация: ![]() ![]() ![]() |
Иногда, просто нужно нажраться!!!
Держи... Се начнем повесть сию... Не начнем, а продолжим... ;) Итак, уважаемые, позвольте мне представить мой туториал №1. Конечно это не принципиально, но может писать не ТУТОРИАЛ, а как-нибудь по-другому, хотя бы по-английски; впрочем - это на твое усмотрение. Он посвящен основам программирования графики на паскалевском ассемблере. Он предназначен для тех, кого достала тормознутость графики на пасе (а работать с графикой с его процедурами я бы не советовал - мееедленно...), кто хотел бы написать БЫСТРУЮ игру, да и для тех, кому вообще интересен асм. Внимание: Данные эксперименты не совсем совместимы с модулем Graph, поэтому крайне нежелательно его включать. В каком месте?? Для использования примеров вам необходима карточка VGA, имеющая режим 320*200, TP версии 6.0 и выше, и желание разобраться. Не думаю, что сейчас хоть у кого-нибудь есть чиста VGA-адаптер; напиши совместимый. В сегодняшней, первой части, я расскажу о том, что из себя представляет режим 320*200 8 бит, как его врубить, и как с ним работать. Этот режим имеет номер 13 в шеснацатеричной системе счисления или 19 в десятичной. В дальнейшем 16-теричный вид будет отмечаться буквой h (Например 13h) а десятичный отмечатся не будет (19). Не надо думать, что все на свете такие валенки; хотя также на твое усмотрение. Немного теории: Раз у нас 8-битный режим, то 1. На каждую ячейку(я.п.) памяти приходится по одной точке! Это просто чудесно! т.к. не рассматриваются случаи, когда в один байт картинки вмещается 2 точки (в 16ти цветных режимах), а то работа по разделению байта - просто геморой. Случай 4-битного цвета в принципе тобой не описывается, так нечего его и затрагивать, а вывод точки там осуществляется отнюдь не так называемым "РАЗДЕЛЕНИЕМ БАЙТА". 2.Мы можем работать с 2^8=256 цветами (в отличие от 16 в пасе)!!!!!!!!! Объясни почему 2^8. 3. Базовый адрес памяти, начиная с которого изображение в графических режимах выводится на монитор, равен 0A000:0000h. следующие 64000(320*200) байта в данном режиме как раз и выводятся на экран. Адрес видеобуфера, а не БАЗОВЫЙ АДРЕС ПАМЯТИ 5. Для возврата из графического режима я буду использовать текстовый режим № 3(80*25*16) Ну так вот, для того, чтобы менять режимы будем использовать функцию BIOS установки режима: ------------------------------------------------------------------------ Установка видеорежима (прерывание 10h): На входе: ah=0 ; Установить режим al = ; Номер режима ------------------------------------------------------------------------ В нашем случае: ------------------------------------------------------------------------ Где директива ASSEMBLER????????????????????????????????????? procedure Set13h; begin asm mov ah,00h ; Установить режим mov al ,13h ; Номер режима 320*200*256цв int 10h ; Номер прерывания end; end; ------------------------------------------------------------------------ ------------------------------------------------------------------------ procedure Close13h; begin asm mov ah,00h ; Установить режим mov al ,03h ; Текстовый режим 80*25*16цв int 10h ; Номер прерывания end; end; ------------------------------------------------------------------------ Хорошо, вот мы и попали в режим 320*200*256 - возможно, скажете вы, - но Graph использовать не рекомендуют, так что же нам здесь делать? Убери слово GRAPH. Ну... для начала давайте очистим экран Так где же эта проклятая очистка флага направления?????????????? О которой я талдычу уже долгое время... ------------------------------------------------------------------------ procedure clscr(col:byte); begin asm mov ax,0A000h mov es,ax xor di,di mov al,[col] mov cx,64000 rep StosB end; end; ------------------------------------------------------------------------ Итак, введя этот код вы получите процедуру закраски экрана. А теперь, давайте я пасскажу о ней поподробнее... Хрень, найди другое понятие. Сегмент - это часть адреса, которая указывает от какой ячейки начинать отсчет смещения. Он имеет размер 64Кб (65536 байт). Каких еще переменных, если это CSeg, DSeg or someting else, то будь добр напиши. В языках программирования используют несколько переменных, которые содержат сегменты, это cs,ds,es,ss,gs,fs. В паскале реально используются лишь первые 4. О стеке подробнее. И вообще, если затрагиваешь какую-то новую тему, старайся дать как можно больше инфы... cs - сегмент кода, обычно не трогается, ds - сегмент данных, здесь размещаются данные, после использования в паскале желательно восстанавливать. ss - сегмент стэка, в этом сегменте хранится то, что заносится в стек(в ручную или при вызове процедур). Стек - что-то типа временной памяти с последовательным доступом. es,fs,gs - дополнительные регистры, на 'всякий случай'. СМ. СЕГМЕНТ Смещение - это вторая часть адреса, которая указывает на я.п. от начала сегмента. Принимает значения от 0 до 65535(по кол-ву байт в сегменте). Не любые. Обычно, для адресации я.п. используют индексные регистры di и si, но можно использовать и любые другие. А как это происходит???????????????????????? Сегмент и смещение занимают по 16 бит(2 байта) и преобразуются в 20-ти битный адрес. mov ax,0a000h mov es,ax Это связано не с отсутствием команд, а обусловлено спецификой архитектуры проца Двумя этими командами мы помещаем в регистр es сегмент адреса видеопамяти(A000). Напрямую помещать адрес нельзя, т.е. запись типа mov es,0a000h является неверной!! По-моему это связано с отсутсвием кода команд в системе операций процессора. Объясни как очищает xor di,di Туманно как-то Эта команда очищает регистр индекса di, для того, чтобы в es:di лежал полный адрес начала выводимой памяти... Индекс di используется для "скольжения" по сегменту, т.е. он адресует ячейку памяти с номером, указанную в нем. Внимание! Команда mov [di],5 ничего никуда не положит!!! Во-первых компилер выдаст ош. так как не поймет размер числа пять (нужно вставить описатель word/byte/dword ptr). Но даже если мы это и поставим, то по умолчанию адресация идет через регистр DS!!!!! Короче - переделать Запись вида mov di,5 обозначает адресацию 5-ой ячейки, а запись вида mov [di],5 обозначает что в ячейку es:di будет помещено значение 5. Правда, в паскале это не так. В паскале для помещения значения 5 по адресу es:di оное значение помещается в регистр, допустим, аl и используется запись вида mov es:[di],al. mov al,[col] Здесь я помещаю в al номер цвета закраски фона. mov cx,64000 rep StosB команда цикла rep повторяет следующую команду. количество повторов лежит в регистре CX. Ее можно заменить на команду цикла loop: @l1: StosB loop @l1 Команда rep сначала проверяет регистр cx на равенство 0, а затем, если он не равен, убавляет его на 1, если равен, то цикл прекращается и программа идет дальше, в отличие от команды loop, которая сначала уменьшает cx на 1, а затем проверяет его на 0. Т.е. если вы поместите в cx 0, то команда rep не выполнится ни разу, а команда loop будет выполняться 65535 раз(по максимальному размеру cx) команда STOSB - es:[di]=al; di=di?1. Помещает содержимое al в я.п. по адресу es:di. В зависимости от df (флаг направления) уменьшает/увеличивает индекс di на 1. Если df = 0 то di увеличивается а если df=1, то di уменьшается. Поэтому я и указал в описании команды знак ?. Устанавливается df (df=1) командой std, а очищается - командой cld. Пример: program darktut; uses crt; procedure set13h; begin asm mov ax,0013h int 10h cld end; end; procedure close13h; begin asm mov ax,0003h int 10h end; end; procedure clscr(col:byte); begin asm push 0a000h pop es xor di,di mov cx,64000 mov al,col rep stosb end; end; begin randomize; set13h; repeat clscr(random(256)); delay(20000); until keypressed; close13h; end. Happy codding!!!!!!!!!!!!! З.Ы. Если вы хотите немного оптимизировать процедуру очистки экрана - то можете уменьшить значение счетчика в 2 раза и пересылать сразу по 2 байта: Туманно, в плане РАСШИРЕНИЯ ЦВЕТА. mov ah,al ;расширяю цвет... mov cx,32000 rep StosW команда StosW: es[di]=ax; di=di+2; Где прогнать-то, я то знаю, а другие вряд-ли. З.Ы.Ы. Если вы хотите посмотреть, как будет выполнятся программа, можете ее прогнать пошагово, открыв окно Debug->Registers и нажимая F7. Заметил З.Ы.Ы.Ы. Просьба, если заметите неточности, или у вас есть предложения/просьбы/коментарии - высказывайте все либо на форуме forum.pascal.dax.ru, либо лично мне по почте. Copyright by Dark. Моя почта: darkmaze@yandex.ru Debugged & corrected by GLuk |
___ALex___ |
![]()
Сообщение
#8
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 282 Репутация: ![]() ![]() ![]() |
"Команда mov [di],5 ничего никуда не положит!!! Во-первых компилер выдаст ош.
так как не поймет размер числа пять (нужно вставить описатель word/byte/dword ptr). Но даже если мы это и поставим, то по умолчанию адресация идет через регистр DS!!!!! Короче - переделать" на счёт первых двух строк всё неверно компилятор должен знать размер памяти адресуемой адресом в ds:di в которую надо "положить" число пять писать надо типа mov byte ptr [di],5 пример для туториала: если начиная с адреса ds:di в ОП находится следующая последовательность байт: DF 10 01 FA CD 13 то после выполнения команды | память изменится следующим образом mov byte ptr [di],5 05 10 01 FA CD 13 mov word ptr [di],5 05 00 01 FA CD 13 mov dword ptr [di],5 05 00 00 00 CD 13 значения квалификаторов: byte - один байт word - два байт dword(double word) - 4 байта И запомните правило - младший байт хранится по младшему адресу Народ кто-нибудь кроме нас это читает? |
Shadow |
![]()
Сообщение
#9
|
![]() Lonely_Raven ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 640 Пол: Мужской Репутация: ![]() ![]() ![]() |
:D
-=-= Да-а-а :-/ -=-=-= :'( -------------------- Программа делает то что вы ей приказали а не то что бы ВАМ хотелось бы.
МЕРФИ --------------------- RTFM - Read the fucking manual --------------------- http://www.livejournal.com/users/lonley_raven/ |
___ALex___ |
![]()
Сообщение
#10
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 282 Репутация: ![]() ![]() ![]() |
народ может всё-таки сначала начать в тутореале объяснять основы асма, давать задания небольшие народы
чтоб "оживить" процесс обучения? а то ведб без основ далеко не уедешь ну как Вы ? :) |
GLuk |
![]()
Сообщение
#11
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 775 Пол: Мужской Репутация: ![]() ![]() ![]() |
2 ___Alex___: По поводу цитаты: это в плане я неправильно что-то подправил?????????
Shadow, а что ДА-а-а - ТАК НАДО! |
___ALex___ |
![]()
Сообщение
#12
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 282 Репутация: ![]() ![]() ![]() |
to GLuk
да ерунда всё это ;) |
GLuk |
![]()
Сообщение
#13
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 775 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата народ может всё-таки сначала начать в тутореале объяснять основы асма, давать задания небольшие народы чтоб "оживить" процесс обучения? а то ведб без основ далеко не уедешь ну как Вы ? :) Можно попробовать; Только где народу набрать?!?!?! :) А по поводу ерунды, ты написал то же самое что и я, поэтому и возник квестчин |
___ALex___ |
![]()
Сообщение
#14
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 282 Репутация: ![]() ![]() ![]() |
я думаю надо сначала создать тему на счёт этого типа приглашаем на обучение асму...но не в разделе по асму так как многие я думаю сюда просто не заходят
как-то это выделить!( |
GLuk |
![]()
Сообщение
#15
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 775 Пол: Мужской Репутация: ![]() ![]() ![]() |
Что ж можно постить это в новостях?
|
___ALex___ |
![]()
Сообщение
#16
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 282 Репутация: ![]() ![]() ![]() |
с другой стороны кому надо тот всегда сам всё изучит...
пусть народ СКАЖЕТ надо ему это или нет... |
___ALex___ |
![]()
Сообщение
#17
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 282 Репутация: ![]() ![]() ![]() |
да запостите такую тему
а там посмотрим по жедающим |
Dark |
![]()
Сообщение
#18
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 408 Пол: Мужской Репутация: ![]() ![]() ![]() |
Угу, ок у меня есть инфа и для начала... т.е. ввод/вывод текста в текст.режиме, работа с файлами, и т.д. и т.п.
-------------------- - Где я?
- Во тьме. - В какой тьме? - Во тьме твоего мозга. |
Dark |
![]()
Сообщение
#19
|
![]() Знаток ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 408 Пол: Мужской Репутация: ![]() ![]() ![]() |
;D
-------------------- - Где я?
- Во тьме. - В какой тьме? - Во тьме твоего мозга. |
GLuk |
![]()
Сообщение
#20
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 775 Пол: Мужской Репутация: ![]() ![]() ![]() |
Ты б домучил сначала туториал №1... ;)
|
![]() ![]() |
![]() |
Текстовая версия | 12.09.2024 2:49 |