Ассемблер?
Это просто! Учимся
программировать Выпуск N 030 (XMS-память) |
Здравствуйте, уважаемые подписчики!
Сегодня в номере:
Благодарю Вас, что подписались на рассылку "Ассемблер? Это просто! Учимся программировать". Надеюсь, что Вы не останетесь равнодушны к ней и почерпнете море полезной информации, а также повысите свой уровень в "общении" с IBM-совместимыми компьютерами.
Прежде, чем приступать к изучению материала в данном выпуске, Вам необходимо внимательно ознакомиться с предыдущими. Я уверен, что Вы очень быстро и без труда догоните остальных подписчиков, не смотря на то, что у нас уже 30 выпуск.
Все, что нужно для изучения Ассемблера (предыдущие выпуски, необходимые программы, документацию, форму для подачи вопроса экспертам, а также многое другое), можно найти на сайте http://www.Kalashnikoff.ru. Рекомендую Вам сперва ознакомиться с разделом "Для новых подписчиков".
Для тех, кто не
имеет выхода в Интернет.
К огромному сожалению, я пока
не имею постоянного доступа к Интернету и почте. Поэтому высылка
архива по e-mail временно
приостановлена... Извините за
доставленные неудобства...
Тусоffка |
Вот, уважаемые читатели, и прошла первая тусоffка, посвященную программированию на Ассемблере.
Что можно сказать? Если честно, то я планировал, что все это произойдет совсем по-другому. Но то, что получилось, это тоже не плохо. Я очень надеюсь, что следующая тусоffка пройдет более массово и более слажено.
Тем не менее, я благодарю всех, кто пришел! Огромное вам всем спасибо!
Т.к. я потерял все, имеющиеся у меня, электронные адреса и номера ICQ подписчиков, то хотел бы попросить написать мне тех, кто присутствовал на тусоffке. Мне нужно выслать вам кое-что... Как только я получу доступ к почте, сразу вам отвечу.
Отпуск |
Уважаемые читатели! В настоящий момент я нахожусь в отпуске и не имею постоянного выхода в Интернет, поэтому не могу отвечать на ваши письма. Но как только я вернусь к своим делам, то сразу сообщу об этом на сайте.
Этот выпуск я отправляю из интернет-кафе. Поэтому просьба: не пишите пока мне письма, т.к. я все равно не смогу отвечать...
________
Недавно удалось посмотреть объем своего почтового ящика и был безмерно удивлен тем, что его размер порядка 120 Мб!!! Это ж сколько писем-то пришло за месяц!!!
________
Обратите также внимание, что я не закачал на сайт файлы-приложения в архиве. К сожалению, не было возможности. Поэтому вам придется сохранить файл старым добрым способом, а именно: скопировать в буфер обмена, а затем вставить в какую-нибудь оболочку.
________
Находясь в отпуске вдалеке от Интернета, у меня появилось много свободного времени, которое я посвящаю написанию книги. За неделю дела продвинулись очень далеко. И это хорошо! Скоро будет готово!
В книге будут также приведены некоторые интересные письма подписчиков, ответы экспертов из рассылки FAQ, а также многое другое (если технический редактор не вырежет это). Если кто-либо из вас не согласен с тем, чтобы опубликовать вашу информацию в книге, то напишите мне.
________
Хотелось бы поблагодарить всех экспертов, отвечающих на вопросы подписчиков в рассылке "Ассемблер? Это просто! Учимся программировать (FAQ)". Даже не знаю, чтобы я делал без вас...
Выражаю отдельную благодарность эксперту Dron за оказанную помощь.
В прошлом выпуске я опубликовал письмо одного подписчика, который предложил попробовать написать свою собственную операционную систему. Я даже не ожидал, что эту идею поддержат такое количество читателей (порядка 48 человек)!
В настоящий момент открыта рассылка, которую ведет эксперт Dron. Уже вышло несколько номеров. Подписаться можно в приведенной ниже форме.
Надеюсь, что рассылка будет интересна вам!
1.
XMSmem.asm |
2.
XMSblock.asm |
3. XMScopy.asm |
Сегодня рассмотрим работу XMS-памяти. А именно:
В приложении вы видите три файла, каждый из которых выполняет свою отдельную функцию. Как обычно будем изучать от простого к сложному (XMSmem, XMSblock, XMScopy).
Прежде, чем приступать к рассмотрению материала, я хотел бы отметить следующие аспекты:
1. Для получения доступа к XMS-памяти необходимо загрузить драйвер HIMEM.SYS либо подобный ему, который откроет линию A20, а также загрузит процедуры для работы с расширенной памятью.
2. Для использования расширенной (XMS) памяти в DOS, необходимо прибегать к помощи прерываний и процедур. Иного способа не существует. Пересылка данных при помощи команд MOVS не годится. Также невозможно читать, например, файл сразу в расширенную память.
3. Работа с XMS-памятью задача
нетривиальная, как может
показаться на первый взгляд. Более
того, отладчики типа AFD, CodeView, Turbo
Debugger и т.п. не позволяют
просматривать содержимое
расширенной памяти. Это значит, что
при возникновении каких-либо
ошибок в программе, придется самому
исследовать и искать ошибку (без
помощи отладчика), что, безусловно,
усложняет процесс отладки.
Однако, подобных трудностей не
возникает у программ, которые
написаны под ОС Windows. В данной
операционной системе используется
совсем другой принцип обращения к
расширенной памяти (примерно так,
как мы обращаемся к основной памяти
в DOS).
Программа
XMSmem.asm.
Подготовка к
использованию расширенной памяти и
вывод объема XMS-памяти.
Теперь можно приступать к изучению материала.
Первое, что мы сделаем, - определим объем доступной XMS-памяти, и выведем кол-во килобайт на экран при помощи известной нам уже процедуры с использованием сопроцессора (ее мы рассматривать уже не будем) (см. файл XMSmem.asm - мы пока будем его рассматривать как самый простой).
Как уже отмечалось выше, для того, чтобы использовать расширенную память, необходимо чтобы в памяти присутствовал специальный драйвер, который бы открыл доступ к ней. В DOS / Windows такой файл называется HIMEM.SYS. Если загрузить DOS без этого драйвера, то программы смогут обращаться только к основной памяти (640 Кб). Следовательно, все файлы-приложения будут работать только, если загружен указанный выше файл (или его аналог).
Первое, что нужно сделать - проверить наличие драйвера HIMEM.SYS в памяти. Это позволяет сделать функция 4300h прерывания 2Fh:
Функция 4300h прерывания 2Fh - проверка на присутствие в памяти драйвера HIMEM.SYS:
Вход: | AX = 4300h |
Выход: | AL = 80h - драйвер загружен |
Делаем буквально следующее (во избежание недоразумений, проверка будет осуществляться во всех трех файлах-приложениях):
... ;Проверим на наличие Himem.sys в памяти... mov ax,4300h int 2Fh cmp al,80h je Himem_loaded ;Если AL = 80h, то Himem.sys загружен. ;Иначе выводим сообщение о том, что Himem в памяти не обнаружен... ... |
Если драйвер присутствует, то можно попробовать отвести блок расширенной памяти. Для этого вызываем процедуру Prepare_XMS, которая подготовится к работе с расширенной памятью, а также отведет блок.
Все процедуры по управлению XMS-памятью вызываются не через прерывания (как функции DOS - INT 21h), а с использованием команды дальний CALL и указанием после нее сегмента и смещения самой процедуры. Получить точку входа (адрес) процедур по управлению XMS-памятью позволяет функция 4310h прерывания 2Fh:
Функция 4301h прерывания 2Fh - получить точку входа процедур управления XMS-памятью:
Вход: | AX = 4310h |
Выход: | ES = сегмент, BX = смещение |
Ниже рассмотрим это на примере.
После того, как получили точку входа, все остальные обращения к процедурам работы с XMS-памятью будут осуществляться следующим образом (естественно, предварительно подготовив регистры или массивы данных):
call dword ptr cs:XMS_Addr
Итак, получаем обработчик XMS-функций и количество килобайт расширенной памяти:
... mov ax,4310h int 2Fh mov word ptr XMS_Addr,bx mov ah,88h
;Получить
кол-во Кб XMS-памяти |
Как видно из примера, функция возвращает количество килобайт (НЕ байт!) в 32-х разрядный регистр EDX.
Теперь осталось только вывести полученный результат, используя написанную нами и изученную процедуру вывода десятичного числа (Out_dec).
Обращаю ваше внимание на тот момент, что количество килобайт свободной XMS-памяти возвращает операционная система, которая берет информацию не из CMOS, а ведет учет самостоятельно. Это значит, что та информация, которую вернет функция, может не соответствовать реальной (DOS может указать не только реальный объем XMS-памяти, но и добавить к нему размер SWAP-файла Windows, либо наоборот показать меньший размер, чем есть на самом деле, вычтя из реального объема размер памяти, отведенный под кэш).
Очень надеюсь, что все понятно!
Программа
XMSblock.asm.
Чтение файла в
расширенную память и вывод его на
экран.
Рассматривать подготовку и отведение блока расширенной памяти мы уже не будем. В данном файле все происходит аналогично вышеописанному, кроме того, что мы еще и отводим блок расширенной памяти при помощи функции 09h процедуры управления XMS-памятью. При этом DX должен содержать размер отводимой памяти в килобайтах:
... mov ah,9 mov dx,1024 ;Отводим 1024Кб XMS-памяти call dword ptr XMS_Addr or ax,ax ;Ошибка? jnz XMS_OK ... XMS_OK: mov XMS_id,dx ;Сохраним ID отведенного блока ... |
В случае, если произошла ошибка (запрашиваемый блок больше имеющегося в распоряжении и т.п.), AX не равен нулю и содержит код ошибки.
Если ошибки не произошло, то DX содержит идентификационный номер отведенного блока. В дальнейшем мы будем обращаться к отведенному блоку, используя этот номер (как при открытии файла функции 3Dh прерывания 21h выдает номер открытого файла).
______________
Итак, теперь рассмотрим работу с расширенной памятью.
Как я уже упоминал выше, загружать данный напрямую в XMS-память в DOS невозможно. Для этого используется основная память (640 Кб). Сперва загружаем данные в отведенный массив в основной памяти, затем при помощи специальной процедуры пересылаем их в расширенную. Пересылка осуществляется блоками, но не более, чем по 64Кб.
В программе XMSblock.asm мы сперва читаем файл C:\AUTOEXEC.BAT в отведенный массив в основной памяти и выводим. Затем перебрасываем прочитанные байты в расширенную память и обратно в основную, но уже по другому адресу. И снова выводим то, что перебрасывали. Идентичность выводимой информации подтверждает то, что программа не имеет ошибок.
Структура массива при работе с XMS-памятью
Для работы с XMS-памятью (пересылка данных) заведем специальный массив. Для удобства зададим каждой переменной название. В дальнейшем адрес данного массива будет загружаться в регистры DS:SI перед вызовом специальных подфункций функции управления XMS-памятью.
... XMS_str dd 0 XMS_src dw 0 XMS_offsrc dd 0 XMS_rec dw 0 XMS_offrec dd 0 ... |
;Кол-во байт для пересылки ;Источник ;Смещение в блоке-источнике или адрес в основной памяти ;Идентификатор приемника ;Смещение в блоке-приемнике или адрес в основной памяти |
Рассмотрим отдельно каждую переменную.
1. XMS_str (два слова) - должна содержать количество байт для пересылки из основной памяти в XMS либо наоборот.
2. XMS_src (слово) - указывает идентификатор источника. Если эта переменная равна нулю, то источником (откуда пересылаются данные) является основная память. В противном случае, переменная должна содержать идентификатор отведенного блока XMS-памяти, который получаем при отведении блока (см. выше - XMS_id).
3. XMS_offsrc (два слова) - содержит смещение в блоке-источнике (если копирование идет из расширенной памяти в основную) или сегмент:смещение в основной памяти (если копирование идет из основной памяти в расширенную).
4. XMS_rec (слово) - указывает идентификатор приемника. Если эта переменная равна нулю, то приемником (куда пересылаются данные) является основная память. В противном случае, переменная должна содержать идентификатор отведенного блока XMS-памяти, который получаем при отведении блока (см. выше - XMS_id).
5. XMS_offrec (два слова) - содержит смещение в блоке-приемнике (если копирование идет в расширенную память из основной) или сегмент:смещение в основной памяти (если копирование идет из расширенной памяти в основную).
Теоретически мы рассмотрели работу с XMS-памятью. Вам осталось лишь изучить внимательно прилагаемый файл XMSblock.asm и описания к нему.
Программа
XMScopy.asm.
Копирование
файла с использованием расширенной
памяти.
ВНИМАНИЕ!
1. Программа корректно
копирует файл, размер которого не
превышает объем XMS-памяти,
установленной в вашем компьютере!
Т.е. Если в вашей машине стоит 16Мб
ОЗУ, то максимальный размер файла,
который можно скопировать с
помощью этой программы, будет 16 Мб
минус 640 Кб.
2. Программа копирует файл C:\FILE.TXT в C:\FILENEW.TXT.
Все эти недоработки вы сможете сами легко доделать. Я же привел простейший алгоритм копирования файла, дабы не нагружать рассылку. Впоследствии мы будем использовать подобный алгоритм в нашей оболочке.
Принцип работы программы:
Уверен, что если вы уяснили весь приведенный выше материал, то и без проблем разберетесь с этой программой. Все элементарно!
______________
А на сегодня все! Я начинаю готовить следующий выпуск. До встречи, друзья мои!
1. Рассылка Сергея Никифорова "Программирование на Visual Basic и ASP" на Subscribe.ru (код рассылки: comp.soft.prog.vbs). Название и сайт автора: Visual Basic Streets, http://www.vbstreets.ru.
2. Рассылка "Мир программирования на Visual BASIC и HTML" (http://soobcha-vb.narod.ru/alex).
С уважением,
Калашников Олег: Assembler@Kalashnikoff.ru
Мой ICQ No.: 68951340
URL сайта подписчиков: http://www.Kalashnikoff.ru
Форма для подачи вопроса: http://www.Kalashnikoff.ru/Experts/Question.html
______________
По вопросам сотрудничества, рекламы и спонсорства обращайтесь:
(C) Москва, 2001. Авторское право принадлежит Калашникову О.А. Публичное размещение материала из рассылки, а также его использование полностью или частично в коммерческих или иных подобных целях без письменного согласия автора влечет ответственность за нарушение авторских прав. |