- •Минобрнауки россии
- •Е.В. Грачева Системное программное обеспечение персональных эвм
- •1 Программирование в операционной среде
- •1.1 Программирование в среде однозадачной операционной системы
- •1.2 Программирование в среде ос Windows
- •1.2.1 Основные понятия
- •1.2.2 Программный интерфейс
- •1.2.2.1 Сообщения, очередь сообщений
- •1.2.2.2 Процедура окна
- •1.2.3 Использование динамических библиотек
- •1.2.3.1.Описание api-функции LoadLibrary
- •1.2.3.2 Описание функции GetProcAddress
- •1.2.3.3 Описание функции FreeLibrary
- •1.2.4 Описание некоторых api-функций
- •1.2.4.1.Функции для создания пользовательского интерфейса
- •1.2.4.1.1 Ввод данных с клавиатуры
- •1.2.4.1.2 Ввод данных с помощью "мыши"
- •1.2.4.1.3 Диалоговые окна
- •1.2.4.2 Функции для получения информации о системе
- •1.2.4.2.1 Информация об аппаратной конфигурации
- •1.2.4.2.3 Конфигурация ос
- •1.2.4.2.4 Системные параметры
- •1.2.4.2.5 Внешний вид системных элементов
- •1.2.4.3 Функции управления памятью
- •1.2.4.3.1 Основные функции управления памятью
- •1.2.4.4.Функции управления файлами
- •1.2.4.4 Функции управления некоторыми устройствами
- •Контрольные вопросы
- •35. Охарактеризовать функцию для определения конфигурации ос
- •36. Охарактеризовать функции об установке системных параметров.
- •2.Ассемблеры
- •2.1 Архитектура процессоров ia-32
- •2.1.1.Основная исполнительная среда микропроцессора с архитектурой ia32
- •2.1.2 Режимы работы и используемая модель памяти процессоров с архитектурой ia32
- •2.1.3 Архитектура ia-32 системного уровня
- •2.2.Программирование на языке ассемблера
- •2.2.1 Метки
- •2.2.2 Директивы
- •2.2.3 Формат команды
- •2.2.4 Система команд микропроцессоров с архитектурой ia32
- •2.2.4.1 Команды пересылки данных
- •Ins строка, dx
- •2.2.4.2 Арифметические операции
- •2.2.4.3 Операции сдвига
- •2.2.4.4 Битовые операции
- •2.2.4.5 Команды для организации циклов
- •1.3.1.1 Команды сравнения
- •2.2.4.6 Команды передачи управления
- •2.2.4.7 Системные команды
- •2.2.4.8 Команды математического сопроцессора
- •2.2.5 Технология программирования
- •2.3 Макроязыки
- •3.Трансляторы
- •3.1 Структура компиляторов и интерпретаторов, лексический, синтаксический и семантический анализаторы, генератор кода
- •3.1.1.Распределение памяти, виды переменных
- •3.1.2.Статическое и динамическое связывание
- •3.2 Загрузчики
- •3.2.1 Функции загрузчика
- •3.2.1 Настраивающий и динамический загрузчики
- •3.3 Подключение библиотек
- •4. Формальные языки и грамматики
- •4.1 Типы грамматик
- •4.1.1 Вывод цепочек
- •4.1.2 Конечный и магазинный автоматы, распознаватели и преобразователи, построение автомата по заданной грамматике
- •Приложения Приложение а
- •Оглавление
- •4. Формальные языки и грамматики
2.2.3 Формат команды
Рисунок 6 – Формат команды
Поля Mod R/M и SIB (пост-байт) – определяют тип адресации
Рисунок 7 – Формат байта Mod R/M
Поля Mod и R/M – формируют 32 типа адресации: 8 регистровых и 24 типа обращений к памяти
Поле Reg/OpCode – определяет либо один из регистров, либо в нем хранится дополнительные 3 бита кода операции
Поле R/M может определять либо регистр как операнд, либо использоваться в комбинации с полем Mod для определения типа адресации.
Поля SIB используются для формирования линейного адреса.
Рисунок 8 – Схема формирования адреса операнда
Поле Scale (символ S) – 2 бита (7 и 6)
Поле Index (символ I) – 3 бита (5, 4 и 3)
Поле Base (символ B) – 3 бита (2, 1 и 0)
Способы адресации основаны на различных вариациях полей Mod R/M и SIB:
Непосредственная – в команде указывается само значение операнда
Mov ax,0ffffh – где Mov – мнемоника команды перемещения данных
Ax – название регистра-приемника данных
0ffffh – непосредственно значение, записываемое в регистр. Значение всегда начинается с цифры. Для шестнадцатеричных чисел, начинающихся с символа необходимо вначале ставить цифру 0. Символ в конце числа означает систему счисления, в которой представлено число, по умолчанию все числа принимаются десятичными. «h» – 16 с/с, «O» – 8 c/с, «b» – 2 с/с.
Регистровая – в команде указываются имена регистров, являющихся источником и приемником данных. Некоторые команды (умножения и деления) хранят операнды не в одном, а в паре регистров (в результате умножения получается слово двойной длины, а делимое должно быть длиннее делителя в 2 раза), при этом пара регистров разделяется двоеточием: EDX:EAX, где старшие 32 разряда в EDX, а младшие – в EAX.
Mov ax,bx; где AX – регистр-приемник данных, а ВХ – регистр-источник данных
Адресация операндов, находящихся в памяти
Ячейка памяти адресуется с помощью селектора сегмента (сегментного регистра) и смещения (OFFSET). Смещение может быть 32-х разрядным или 16-ти разрядным. Формирование линейного адреса происходит согласно рисунку 30.
Рисунок 9 – Схема формирования адреса в процессорах IA32
Селектор сегмента – определяется сегментным регистром. По умолчанию приняты следующие правила использования сегментных регистров:
CS – указатель на сегмент кода, по умолчанию используется для выборки команд
DS – указатель на сегмент данных, по умолчанию используется для всех обращений к данным, за исключением операций со стеком и строками
SS – указатель на сегмент стека, по умолчанию используется для обращения к стеку, а также при обращении к памяти с использованием регистров ESP или EBP в качестве базовых регистров.
ES – указатель на дополнительный сегмент данных, по умолчанию используется для адресации строк.
При необходимости можно указывать название сегментного регистра в команде (на машинном уровне, формируется соответствующий префикс команды), например: необходимо сохранить данные в сегмент, адрес которого указан в ES
Mov es:[ebx], eax – содержимое регистра eax запишется в сегмент, указанный в es со смещением, равным содержимому ebx
Следующие типы адресации определяются способом вычисления смещения:
Прямая – смещение указывается непосредственно в команде
Mov ax, es:0001 – в регистр ах загружается слово из сегмента памяти на который указывает регистр es, смещение равно 0001. При написании программ, вместо цифрового представления адреса используется символьное обозначение ячейки, т.е. имя переменной. Компилятор, на этапе преобразования исходного текста программы в машинный код, самостоятельно вычислит смещения каждой объявленной переменной относительно начала сегмента, и в программе будет использовать этот, вычисленный, адрес. Т.е. команды будет выглядеть следующим образом
Mov ax, peremennaya, где peremennaya – имя переменной.
Косвенная – тип адресации, при которой смещение операнда относительно начала сегмента указывается неявно. Разбивается на несколько подтипов:
Базовая – указывается только базовый регистр
Например:
Mov [<базовый регистр>], <источник>
Базовая со смещением (displacement) – указывается базовый регистр и смещение относительно его содержимого
Например:
Mov [<базовый регистр >+<число>], <источник>
Индексная с масштабированием и смещением – указывается индексный регистр, число, определяющее масштаб (2,4 или 8) и смещение
Например:
Mov [<индексный регистр>*<масштаб 2, 4 или 8> + <число>], <источник>
Базово-индексная со смещением – указывается базовый регистр, индексный и смещение
Mov [<базовый регистр >+<индексный регистр> + <число>], <источник>
Базовая с масштабируемым индексом и смещением – включает в себя базовый регистр, индексный регистр, масштаб и смещение.
Mov [<базовый регистр>+<индексный регистр>*<масштаб 2, 4 или 8> + <число>], <источник>
Типы данных
Понятие типы данных носит двойственный характер: с точки зрения аппаратной поддержки и с точки зрения логической организации данных. С точки зрения аппаратной поддержки процессор поддерживает следующие типы данных:
Байт – объявляется директивой db в сегменте данных
Слово (2 байта) – объявляется директивой dw в сегменте данных
Двойное слово (4 байта) – объявляется директивой dd в сегменте данных
Учетверенное слово (8 байт) – объявляется директивой dq в сегменте данных (начиная с процессора I80486).
Необходимо отметить, что младший байт каждой переменной занимает младший адрес в памяти, этот адрес и является адресом операнда (переменной!)
С точки зрения логической организации данных, данные могут быть следующих типов:
Цифровые типы данных, которые делятся на целые числа без знака, целые числа со знаком и числа с плавающей запятой.
Целые – числа в диапазоне от 0 до 255 (1 байт)
Со знаком – числа в диапазоне от -128 до +127 (1 байт). Необходимо отметить, что числа со знаком представлены в виде дополнительного кода.
Числа с плавающей запятой – числа в диапазоне от 1.18∙10–38 до 3.40∙10 38 длиной в 32 бита и с точностью 24 бита. Эти числа хранятся в специальных регистрах данных с плавающей запятой (регистры FPU).
Указатели на память:
Ближний указатель (near) – 32-х или 16-ти разрядный адрес, представляющий собой смещение относительно начала сегмента. Его также называют эффективным (effective) адресом. Этот указатель используется в плоской модели памяти и в сегментной модели памяти, если нет необходимости выходить за пределы сегмента.
Дальний указатель (far) – 48-и разрядный адрес, состоящий из 16-и разрядного номера сегмента (селектора) и 32-х разрядного смещения внутри этого сегмента. Для 64-х разрядных операндов дальний указатель содержит 80 бит: 16-и разрядный селектор сегмента и 64-х разрядное смещение.
Битовое поле – представляет собой непрерывную последовательность битов, в которой каждый бит является независимым и может рассматриваться как отдельная переменная. Битовое поле может начинаться с любого бита в байте и может содержать до 32 битов. Доступ к битам и обработка битовых полей осуществляется с помощью специальных команд.
Двочно-десятичные типы данных, т.е. десятичные числа, записанные в двоичной системе счисления делятся на две группы:
Упакованные двоично-десятичные – каждая десятичная цифра записывается в одну тетраду
Неупакованные двоично-десятичные – каждая десятичная цифра записывается в один байт
Массив – структурированный тип данных, состоящий из некоторого числа элементов одного типа. Несмотря на то, что массивы могут быть в общем случае n-мерными, необходимо четко представлять себе, что элементы массива располагаются в памяти последовательно друг за другом. Т.е. физически, двумерный или трехмерный массив ничем не отличается от одномерного массива. Доступ к элементам массива осуществляется с помощью индексов (смещения относительно начала массива).
Например:
Mass db 5,2,3
db 1,4,6
В массиве с именем Mass элемент «5» будет иметь индекс равный 0, элемент «2» – индекс равный 1, элемент «4» – индекс равный 4. И хотя пользователь пытался создать двумерный массив к массиву Mass можно обратиться как к одномерному. Чтобы обращаться к массиву Mass как к двумерному массиву необходимо использовать 2 индекса: адрес начала строки элементов массива и смещение элемента относительно адреса начала строки.
Структуры – тип данных, состоящий из фиксированного числа элементов разного типа. Перед использованием структуры необходимо задать её шаблон:
<имя_структуры> STRUC
<описание_полей>
< имя_структуры >ENDS
В отличие от массива элементы структуры могут быть разных типов. Обращение к полям структуры осуществляется по имени переменной и поля структуры, разделенным точкой.
Например:
Объявление шаблона:
Data STRUC
type db 30 dup (“”); описание типа данных, dup – оператор дублирования
znachen dw; значение типа данных
ENDS
Присвоение значений переменной типа Data:
Danny1 data <”какие-то данные”,'10202'>;
Danny2 data <”новые данные”,'393032'>;
Обращение к значениям переменной типа Data:
Mov ax,Danny1.znachen
