- •Щемелева т.К.
- •Архитектура и программирование реального режима микропроцессоров фирмы intel
- •Учебное пособие
- •Пермь 2001
- •Содержание
- •1.2.Переводы между позиционными системами счисления
- •1.3.Система кодирования символов ascii
- •1.4. Преобразование строки ascii-кодов в двоичное и шестнадцатеричное число
- •1.5. Применение систем счисления в эвм
- •1.6. Контрольные вопросы и задания
- •Тема 2. Представление данных на языке ассемблера и их хранение в памяти пк
- •2.1. Биты, байты и слова
- •2.3. Размещение различных типов данных в памяти пк
- •2.4. Отрицательные числа
- •2.5. Контрольные вопросы и задания
- •Тема 3. Элементы архитектуры персонального компьютера: сегментная память и регистровая структура микропроцессора
- •3.1. Понятие сегмента
- •3.2. Способ адресации ячеек сегментированной памяти
- •3.4. Программистская модель мп i8086. Назначение регистров.
- •Регистры общего назначения
- •Регистры сегментов и указатель команд
- •3.5. Контрольные вопросы и задания
- •Тема 4. Создание программы в ехе-формате
- •4.1. Программы на языке транслятораMasm.
- •4.1.1. Определение сегментов и данных.
- •4.1.2. Структура программы.
- •4.2. Программы на языке транслятораTasm.
- •4.2.1. Особенности транслятора.
- •4.2.2. Определение сегментов и данных .
- •4.2.3. Директива model.
- •4.2.4. Директивы упрощенного описания сегментов.
- •4.2.5. Структура программы.
- •4.2.6. Директивы startupcode и exitcode.
- •4.3. Контрольные вопросы и задания
- •Тема 5. Способы адресации данных в командах языка ассемблер
- •5.1. Регистровая адресация
- •5.2. Непосредственная адресация.
- •5.3. Прямая адресация.
- •5.4. Косвенная регистровая.
- •5.5. Адресация по базе.
- •5.6. Индексная адресация.
- •5.7. Адресация по базе с индексированием.
- •5.8. Контрольные задания.
- •Тема 6. Основные команды языка Ассемблер
- •6.1. Команды пересылки.
- •1) Пересылка данных
- •2) Пересылка адресов
- •4) Пересылка в стек и из стека
- •6.2. Арифметические операции.
- •2) Арифметические операции над двоичными кодами.
- •3) Команда сравнения:
- •6.3. Команды корректировки.
- •6.4. Команды логических операций.
- •1) Поразрядные логические операции:
- •2) Команды сдвига
- •6.5. Команды передачи управления.
- •6.6. Команды организации цикла.
- •6.7. Команды вызова процедур и возврата из них.
- •6.8. Команды прерываний и возврата из них.
- •6.8.1. Функции ввода/выводаDos.
- •6.8.2. ФункцииBios управления экраном.
- •Тема 7. Стек
- •7.1.Стек и сегмент стека
- •7.2.Стековые команды
- •7.3. Доступ к элементам стека
- •Тема 8. Практическая работа на пк.
- •Тема 9. Создание линейных программ
- •9.1 Создание линейной программы.
- •9.1.1. Составление текста программы.
- •9.1.2 Трансляция.
- •9.1.3. Создание исполняемого файла
- •9.1.4.Отладка программы в turbo debugger’е
- •9.2. Контрольные вопросы и задания
- •Тема 10. Организация ветвлений.
- •10.1.Флаги и их назначение.
- •10.2 Команда безусловного перехода jmp
- •10.3 Команды условных переходов
- •10.4. Создание разветвленной программы.
- •10.4.1. Составление текста программы.
- •10.4.2.Трансляция.
- •10.4.3. Создание исполняемого файла.
- •10.5. Контрольные вопросы и задания
- •Тема 11. Организация циклов
- •11.1. Команды управления циклом
- •11.2.Создание циклической программы.
- •11.2.1.Составление текста программы.
- •11.2.2.Трансляция.
- •11.2.3.Создание исполняемого файла
- •11.2.4.Отладка программы в turbo debugger’е
- •11.3. Контрольные вопросы и задания
- •Тема 12. Циклическая разветвленная программа
- •12.1.Создание программы.
- •12.1.1.Составление программы
- •12.1.2.Трансляция.
- •12.1.3.Создание исполняемого файла.
- •12.1.4. Отладка программы в turbo debugger’е
- •12.2.Контрольные вопросы
- •12.3. Контрольные задания
- •Тема 13. Связь ассемблера с языкомPascal.
- •13.1 Общие положения
- •13.2 Организация связи
- •13.3 Передача аргументов (и возврат результата в случае функции)
- •13.4 ДирективаArg
- •13.5 Использование операндов директивыmodel
- •13.6 Передача данных остальных типовPascal
- •13.7 Возврат значения в программу наPascal
- •13.8 КомандыEnter иLeave
- •13.9 Итоги
- •Листинг 1.2. Ассемблерное представление.
- •Тема 16. Рекомдации начинающему программисту
- •Тема 17. Контрольная работа
- •Список литературы
- •Приложение 1 Инструкция по работе с программой Turbo Debugger.
- •Приложение 2 Практическая работа на пк
- •Приложение 3 ключи командной строкиtasmиtlink
13.8 КомандыEnter иLeave
В системе команд микропроцессора имеются специальные команды enter и leave. Их использование позволяет облегчить написание кода пролога и эпилога в процедурах ассемблера, например:
;старый код пролога:
push bp
mov bp, sp
; новый код пролога:
enter 0,0
; … … …
; старый код эпилога:
mov sp, bp
pop bp
;новый код эпилога:
leave
Транслятор ассемблера предоставляет средства в виде директив, которые еще больше упрощают работу программиста по формированию кодов пролога и эпилога. Одной из них является директива arg.
Применение директив arg и local приводит к генерации команд enter и leave при входе и выходе из процедуры. Поочередное комментирование этих директив показывает, что они влияют только на формирование операнда команды enter. При использовании local он равен числу байт, необходимых для размещения в стеке локальных переменных. Это так называемый кадр стека. Если строку с директивой local закомментировать, то команда enter все равно формируется, но с нулевым значением первого операнда. Это говорит о том, что пролог процедуры формируется в любом случае, но директива local позволяет еще и сформировать кадр стека для хранения локальных переменных процедуры. Соответственно, во всех вариантах генерации команды enter в конце процедуры формируется команда leave.
Отметим, что эти средства можно использовать не только для связи Pascal - ассемблер, но и для организации других - межъязыковых связей, в том числе ассемблер - ассемблер.
13.9 Итоги
Язык ассемблера содержит достаточно мощные средства поддержки структурного программирования. В языке ассемблера эта технология поддерживается в основном с помощью механизма процедур и частично с использованием макрокоманд.
Гибкость интерфейса между процедурами достигается за счет разнообразия вариантов передачи аргументов в процедуру и возвращения результатов. Для этого могут использоваться регистры, общие области памяти, стек, директивы extrn и public.
Средства TASM поддерживают связи между языками. Ключевой момент при этом - организация обмена данными. Обмен данными между процедурами на языках высокого уровня и ассемблера производится через стек. Для доступа к аргументам используется регистр bp или (что более удобно) директива arg.
Тема 15. СозданиеWindows-приложения на ассемблере КаркасноеWindows-приложение на языке С/С++.
Мы начинаем с программы на языке С/С++. Во-первых, нам необходимо понять общие принципы построения оконных приложений Windows. Во-вторых мы разберемся с тем, какие средства ассемблера при этом используются.
Приступая к разработке первого Windows-приложения, важно понимать, что сам язык программирования мало влияет на его общую структуру. Это обстоятельство и позволит нам чуть позже с относительной легкостью изменить инструментальное средство разработки Windows-приложения с С/С++ на ассемблер.
Выполнение любого оконного Windows-приложения начинается с главной функции. Она содержит код, осуществляющую настройку приложения в среде операционной системы Windows. Видимым для пользователя результатом работы главной функции является появление на экране графического объекта в виде окна. Последним действием кода главной функции является создание цикла обработки сообщений. Обработка поступающих приложению сообщений осуществляется специальной функцией, называемой оконной. Тело оконной функции имеет определенную структуру. Таким образом, Windows-приложение, как минимум, должно состоять из трех перечисленных элементов. В листинге 1.1 приведен вариант минимального приложения на языке С/С++.
Листинг 1.1. КаркасноеWindows-приложение на языке С/С++
#include <windows.h>
LRESULT CALLBACK WindowProc(HWND ,UINT ,WPARAM ,LPARAM);
char szClassWindow[] = "КаркасноеПриложение"; /*Имя класса окна*/
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)
{
HWND hWnd;
MSG lpMsg;
WNDCLASSEX wcl;
/* Определение класса окна */
wcl.cbSize = sizeof (wcl); //длина структуры WNDCLASSEXA
wcl.style = CS_HREDRAW|CS_VREDRAW; //CS (Class Style) - стиль класса окна
wcl.lpfnWndProc = WindowProc; //адрес функции окна
wcl.cbClsExtra =0; //для внутреннего использования Windows
wcl.cbWndExtra = 0; //для внутреннего использования Windows
wcl.hInstance = hInst; //дескриптор данного приложения
wcl.hIcon = LoadIconA(NULL,IDI_APPLICATION); //стандартная иконка
wcl.hCursor = LoadCursorA(NULL,IDC_ARROW); //стандартный курсор
wcl.hbrBackground =(HBRUSH)GetStockObject (WHITE_BRUSH); // определить заполнение окна белым цветом
wcl.lpszMenuName = NULL; //без меню
wcl.lpszClassName = szClassWindow; //имя класса окна
wcl.hIconSm=NULL; //дескриптор маленькой иконки, связываемой с классом окна
//зарегистрировать класс окна
if (!RegisterClassEx (&wcl))
return 0;
//создать окно и присвоить дескриптор окна переменной hWnd
hWnd=CreateWindowEx(
0, //расширенный стиль окна
szClassWindow, //имя класса окна
"Каркас программы для Win32 на С++", //заголовок окна
WS_OVERLAPPEDWINDOW, //стиль окна
CW_USEDEFAULT, //X-координата верх. левого угла окна
CW_USEDEFAULT, //Y-координата верх. левого угла окна
CW_USEDEFAULT, //ширина окна
CW_USEDEFAULT, //высота окна
NULL, //дескриптор родительского окна
NULL, //дескриптор меню окна
hInst, //идент. приложения создавшего окно
NULL); //указатель на область данных приложения
//показать окно и перерисовать содержимое
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
/* запустить цикл обработки сообщений */
while (GetMessage(&lpMsg,NULL,0,0))
{
TranslateMessage(&lpMsg); //разрешить использование клавиатуры
DispatchMessage(&lpMsg); //вернуть управление Windows
}
return lpMsg.wParam;
} //конец WinMain
LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
//Функция WndProc вызывается операционной системой Windows 95
//и получает в качестве параметров сообщения из очереди
//сообщений данного приложения
{
switch(message)
{
case WM_DESTROY: /* завершение программы */
PostQuitMessage (0);
break;
default:
//Сюда попадают все сообщения, не обрабатываемые в данной оконной функции.
//Далее эти сообщения направляются обратно Windows на обработку по умолчанию
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
Разберем долее подробно суть действии, выполняемых каждым из трех элементов Windows-приложения. В листинге 1.1 видно, что минимальное приложение на языке С/С++ состоит из 2-х функции: главной-WinMain и оконной-WindowProc. Цель WinMain- сообщить системе о новом для нее приложения, его свойствах и особенностях.
Оконная функция получает все сообщения, предназначенные данному окну, и обрабатывает их.
Видимая часть работы каркасного приложения заключается в создании нового окна на экране. Оно отвечает всем требованиям стандартного окна приложения Windows.
В процессе формирования объектного модуля компилятор преобразует исходный текст на языке С/С++ в эквивалентный текст на языке ассемблера. В контексте нашего обсуждения это достаточно ценная информация.
Полученный текст на ассемблере ценен тем, что в нем каждой строке исходного текста программы на языке С/С++ сопоставляется текст на ассемблере. В листинге 1.2 приведен текст.