- •Введение Основные определения
- •Системы счисления Основные определения
- •Двоичная, восьмеричная и шестнадцатеричная системы счисления
- •Смешанные системы счисления
- •Перевод чисел из одной системы счисления в другую
- •Арифметические действия в системах счисления с основанием, отличным от 10
- •Двоично-восьмеричные и двоично-шестнадцатеричные преобразования
- •Обратный и дополнительный коды и их применение в операциях с отрицательными числами
- •Сложение и вычитание чисел со знаком в дополнительном коде
- •Архитектура персонального компьютера История развития вычислительной техники
- •Основные термины и определения
- •Функциональная структура компьютера
- •Архитектура микропроцессора
- •Регистры общего назначения и сегментные регистры
- •Управляющие регистры Регистр cr0.
- •Память компьютера
- •Структура программы на языке Ассемблера Формат кодирования в языке Ассемблера
- •Структура программы на ассемблере
- •Простейшая программа в ос Windows
- •Типы и форматы данных в ассемблере
- •Базовая система команд микропроцессора ia-32
- •Операнды языка ассемблер
- •Стандартные директивы сегментации
- •Макрокоманды
- •Процедуры (функции)
- •Организация интерфейса с процедурой
- •Возврат результата из процедуры
- •Связь ассемблера с языками высокого уровня
- •Обработка прерываний
- •Создание исполняемого файла
- •Отладка программы
- •Математический сопроцессор
- •Представление чисел с плавающей точкой в разрядной сетке вычислительной машины
- •Архитектура сопроцессора
- •Система команд сопроцессора
- •Команды передачи данных
- •Команды загрузки констант
- •Команды сравнения данных
- •Арифметические команды
- •Команды управления математическим сопроцессором
- •Пример программы с использованием команд сопроцессора
- •Сложные типы данных Структуры
- •Объединения
- •Программирование для windows
- •Основы программирования в ос Windows
- •Консольные приложения Windows
- •Работа с файлами в системе Windows
- •Вывод чисел в консоль
- •Оконные (каркасные) приложения Windows
- •Графика в оконных приложениях Windows
- •Ресурсы в Windows-приложениях
- •Приложение 1
Пример программы с использованием команд сопроцессора
О пределить, принадлежит ли точка заштрихованной части плоскости.
Программа запрашивает вещественные координаты точки X и Y, после чего с помощью команды сопроцессора сравнивает координату Y с 2, а X – с (-1). В соответствии с результатом сравнения выдается сообщение о принадлежности или непринадлежности точки.
#include <windows.h>
#include <tchar.h>
void main()
{
float x,y;
int cons=2;
char s[40];
CharToOem(_T("Введите координаты точки X и Y: "),s);
printf(s);
scanf("%f%f",&x,&y);
_asm
{
fild cons
fld y
fcomip ST,ST(1)
jae m
fstp cons ; освобождение стека
mov cons, -1
fild cons
fld x
fcomip ST,ST(1)
jb m
}
CharToOem(_T("Точка принадлежит плоскости."),s);
_asm jmp ext;
m:
CharToOem(_T("Точка не принадлежит плоскости."),s);
ext:
printf(s);
getch();
}
Сложные типы данных Структуры
Часто в приложениях возникает необходимость рассматривать некоторую совокупность данных разного типа как некоторый единый тип. Это очень актуально, например, для программ баз данных, где необходимо связывать совокупность данных разного типа с одним объектом. Такой объект обычно описывается с помощью специального типа данных — структуры. С целью повысить удобство использования языка ассемблера в него также был введен такой тип данных.
По определению структура — это тип данных, состоящий из фиксированного числа элементов разного типа. Для использования структур в программе необходимо выполнить три действия:
Задать шаблон структуры. По смыслу это означает определение нового типа данных, который впоследствии можно использовать для определения переменных этого типа.
Определить экземпляр структуры. Этот этап подразумевает инициализацию конкретной переменной с заранее определенной (с помощью шаблона) структурой.
Организовать обращение к элементам структуры.
Описать структуру в программе означает лишь указать ее схему или шаблон; память при этом не выделяется. Этот шаблон можно рассматривать лишь как информацию для транслятора о расположении полей и их значении по умолчанию. Определить структуру — значит дать указание транслятору выделить память и присвоить этой области памяти символическое имя. Описать структуру в программе можно только один раз, а определить — любое количество раз.
Описание шаблона структуры
Описание шаблона структуры имеет следующий синтаксис:
имя_структуры STRUC
<описание полей>
имя_структуры ENDS
Здесь <описание полей> представляет собой последовательность директив описания данных db, dw, dd, dq и dt. Их операнды определяют размер полей и при необходимости начальные значения. Этими значениями будут, возможно, инициализироваться соответствующие поля при определении структуры.
Местоположение шаблона в программе может быть произвольным, но, следуя логике работы однопроходного транслятора, он должен быть расположен до того места, где определяется переменная с типом данной структуры. То есть при описании в секции данных переменной с типом некоторой структуры ее шаблон необходимо поместить в начале секции данных либо перед ней.
Рассмотрим работу со структурами на примере моделирования базы данных о сотрудниках некоторого отдела. Для простоты, чтобы уйти от проблем преобразования информации при вводе, условимся, что все поля символьные. Определим структуру записи этой базы данных следующим шаблоном:
worker struc ;информация о сотруднике
nam db 30 dup (" ") ;фамилия, имя, отчество
position db 30 dup (" ") ;должность
age dd 20 ;возраст
worker ends
Определение данных типа «структура»
Для использования описанной с помощью шаблона структуры в программе необходимо определить переменную с типом данной структуры. Для этого используется следующая синтаксическая конструкция:
[имя_переменной] имя_структуры <[список_значений]>
имя_переменной — идентификатор переменной данного структурного типа. Задание имени переменной необязательно. Если его не указать, будет просто выделена область памяти размером в сумму длин всех элементов структуры;
список_значений — заключенный в угловые скобки список начальных значений элементов структуры, разделенных запятыми. Его задание также необязательно. Если список указан не полностью, то все поля структуры для данной переменной инициализируются значениями из шаблона, если таковые заданы. Допускается инициализация отдельных полей, но в этом случае пропущенные поля должны отделяться запятыми. Пропущенные поля будут инициализированы значениями из шаблона структуры. Если при определении новой переменной с типом данной структуры все поля структуры инициализируются значениями по умолчанию, то нужно просто написать угловые скобки.
Для примера определим несколько переменных с типом структуры worker:
data segment
sotr1 worker<"Гурко Андрей Вячеславович",'художник',33>
sotr2 worker<"Степанова Ольга Валерьевна",'связист'>
sotr3 worker<> ;все значения по умолчанию
data ends
Методы работы со структурой
Идея введения структурного типа в любой язык программирования состоит в объединении разнотипных переменных в один объект. В языке должны быть средства доступа к этим переменным внутри конкретного экземпляра структуры. Для того, чтобы сослаться в команде на поле некоторой структуры, используется специальный оператор — символ «.» (точка). Он используется в следующей синтаксической конструкции:
адресное_выражение.имя_поля_структуры
адресное_выражение — идентификатор переменной структурного типа;
имя_поля_структуры — имя поля из шаблона структуры, представляет собой смещение поля от начала структуры. Таким образом оператор «.» вычисляет выражение:
(адресное_выражение) + (имя_поля_структуры)
Продемонстрируем на примере структуры worker некоторые приемы работы со структурами. Пусть требуется извлечь в eaх и ebx значения поля с возрастом.
code segment
start:
mov eax, sotr1.age
mov ebx, sotr2.age
...
ret
code ends
или
code segment
start:
lea ebx, sotr1
mov eax, [ebx + worker.age]
mov edx, [ebx + size(worker) + worker.age]
ret
code ends
Язык ассемблера разрешает определять не только отдельную переменную с типом структуры, но и массив структур:
mas_sotr worker 10 dup (<>)
Дальнейшая работа с массивом структур производится так же, как и с одномерным массивом.
Аналогично другим идентификаторам, определенным в программе, транслятор назначает имени типа структуры и имени переменной с типом структуры атрибут типа. Значением этого атрибута является размер в байтах, занимаемый полями этой структуры. Извлечь это значение можно с помощью оператора type. После того, как стал известен размер экземпляра структуры, организовать индексацию в массиве структур можно следующим образом:
...
data segment
mas_worker worker 10 dup(<>)
data ends
code segment
start:
lea esi, mas_worker
mov ecx, 10
mov edx, 0
m1:
mov eax, [esi + worker.age]
add eax, edx
mov [esi + worker.age], eax
inc edx
mov eax, [esi + worker.age]
add esi, size(worker)
loop m1
ret
code ends
end start