mov eax, [00403474h] ; поместить в регистр eax значение находящееся
; по адресу 00403474h
Это простейший способ обратиться к данным, находящимся в памяти.
Косвенно-регистровая адресация - в этом случае адрес операнда размещается в одном из регистров, например:mov eax, [ebx] ; поместить в регистр eax значение находящееся
; по адресу находящемуся в регистре ebx
Как правило, для этого используются регистры esi, edi, ebx, ebp. Содержимое регистра можно изменять (например, в цикле), при этом одна и та же команда будет оперировать различными ячейками памяти.
Базовая адресация - в этом случае адрес операнда (исполнительный адрес) получается как сумма содержимого регистров ebx или ebp и числовой константы, называемой смещением (displacement). Если использован регистр ebx, то будет происходить обращение к данным в памяти, а если регистр ebp– то к стеку. Такой вид адресации можно, например, использовать для доступа к элементу некоторого массива: регистр ebx указывает на начало массива, а смещение представляет собой номер элемента. Индексная адресация - во всех микропроцессорах фирмы Intel по существу аналогична базовой. Адрес операнда вычисляется как сумма содержимого регистров esi или edi и смещения. Базово-индексная адресация (а также – базово-индексная со смещением) - адрес операнда здесь образуется из суммы содержимого регистров ebx (или ebp), регистров esi (или edi) и необязательного смещения. Неявная (или подразумеваемая) адресация - используется, например, при обращении к отдельным флагам или регистру флагов в целом, а также в командах обработки строк (цепочек данных) типа MOVS, SCAS и т. п. Стековая адресация является разновидностью неявной. Операнд находится в стеке, на вершину которого указывает регистр esp. Относительная адресация - в микропроцессорах фирмы Intel не применяется к командам обработки данных, а используется лишь в командах переходов, вызовов подпрограмм и управления циклами. Адрес перехода образуется как смещение относительно текущего содержимого счетчика команд.Отметим, что набор допустимых способов адресации зависит от команды, для того, чтобы узнать какие именно виды адресации поддерживает конкретная команда следует обратиться к справочнику.
Среда разработки Virtual Pascal
Для знакомства с языком ассемблера воспользуемся интегрированной средой разработки Virtual Pascal, данный выбор обусловлен следующими характеристиками среды:
Наличие 32-х битного компилятора, позволяющего создавать 32-х битные приложения для операционных систем Windows, Linux, OS/2. Схожесть интерфейса с изучавшейся ранее средой Borland Pascal (рисунок 16).
Рисунок 16 – Интерфейс Virtual Pascal
Наличие встроенного дизассемблера интегрированного с отладчиком, позволяющего просматривать сгенерированный компилятором код, как в машинных кодах, так и на языке ассемблера.Продемонстрируем работу с отладчиком в режиме дизассемблера на примере простой программы (рисунок 17).
program example;
var
a, b, c: longint;
begin
a := 1;
b := 2;
c := a + b;
end.
Рисунок 17 - Пример программы для отладки
Запустим эту программу в режиме отладки по шагам (например, с помощью пункта меню Run → Step Over). Отладчик остановиться на первой строке программы ( a:=1 ). Затем откроем окно дизассемблера с помощью пункта меню View → CPU (рисунок 18).

Рисунок 18 - Дизассемблер Virtual Pascal
Экран дизассемблера состоит из нескольких частей:
исходный код; регистры процессора (eax – eip, cs – fs); регистр флагов (c – d); оперативная память процесса (программы) в нижней части экрана; стек в нижней правой части экрана.Окно исходного кода содержит как код на языке Паскаль (выделен желтым), так и ассемблерный код. Формат данных в этом окне рассмотрим на примере строки:
example. pas.5 a := 1;
cs:00401030 030578344000 add eax,[403478h]
Поля этих строк имеют следующий смысл:
example. pas - имя файла с исходным текстом программы
5 - номер строки в файле исходного кода
a := 1; - сама строка исходного текста
cs:00401030 - адрес команды в памяти
030578344000 - машинный код команды
add eax,[403478h] - запись команды на языке ассемблера
Команда, которая выполняется в данный момент, подсвечивается символом ►. При активном окне дизассемблера смысл действий Step и Next отладчика несколько изменяется, теперь они выполняют не одну строку, а одну машинную команду.
Поясним дизассемблированный код в нашем примере:
mov DWord Ptr [403474h],1 ; Поместить в 32-х битную (DWord) область памяти
; по адресу 403474h значение 1
mov DWord Ptr [403478h],2 ; Поместить в 32-х битную область памяти значение 2
mov eax,[403474h] ; Поместить в регистр eax значение из области памяти
; по адресу 403474h
add eax,[403478h] ; Сложить значение находящееся в регистре eax со
; значением находящимся по адресу 403478h
; результат поместить в eax
mov [40347Ch],eax ; Значение находящееся в eax поместить в область
; памяти по адресу 40347Ch
Очевидно, что 32-х битная область памяти, начинающаяся с адреса 403474h - это ни что иное, как переменная a, с адреса 403478h - b, 40347Ch - с.
Ассемблерные вставки
В языке программирования Pascal предусмотрена возможность прямой вставки ассемблерных команд в текст программы, это делается при помощи конструкции asm … end, данную конструкцию обычно называют ассемблерной вставкой. В качестве содержимого данной конструкции используется код на языке ассемблера, причем стандарт языка Pascal никак это содержимое не оговаривает, т. е. возможное содержимое ассемблерной вставки может быть различным в различных компиляторах и на различных платформах. Напомним, что мы рассматриваем 32-х битный режим процессора x86 и компилятор Virtual Pascal.
Например, оператор сложения в программе представленной на рисунке 17 может быть переписан с использованием ассемблерной вставки, как показано на рисунке 19.
program example;
var
a, b, c : longint;
begin
a := 1;
b := 2;
asm
mov eax, a
add eax, b
mov c, eax
end
end.
Рисунок 19 - Программа с ассемблерной вставкой
Задание к лабораторной работе
В лабораторной работе требуется написать программу на языке Pascal в соответствии с вариантом, обработку данных (в том числе циклы, если они необходимы) осуществить в ассемблерной вставке.
Написать программу, которая в массиве чисел типа integer находит среднее арифметическое, количество элементов в массиве меньше 32000. Написать программу, вычисляющую количество элементов в массиве до первого нулевого элемента, в случае если нулевого элемента нет, должно возвращаться количество элементов в массиве. Написать программу, производящую сложение чисел произвольной размерности. Числа хранятся в виде массивов типа longint, где 0-й элемент массива - содержит младшие 32 бита числа (с 0-го по 31-й), следующий элемент массива с 32-го по 63-й и т. д. Ввод-вывод данных чисел осуществлять в 16-ричной системе счисления. Написать программу, производящую вычитание чисел произвольной размерности. Числа хранятся в виде массивов типа longint (см. задание 3). Ввод-вывод данных чисел осуществлять из двоичных файлов (длина которых соответственно кратна 4-м). Написать программу, выводящую на экран идентификатор процессора (для процессоров серии 568 и старше), например, для процессоров фирмы Intel: GenuineIntel, для процессоров AMD: AuthenticAMD и т. д. Написать программу, осуществляющую копирование содержимого массива типа char в n-раз больший массив, при этом каждый элемент массива должен повторяться n-раз, т. е., например, из массива 'a', 'b', 'c', при n=3, должен быть сформирован массив 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c' Ввод-вывод массивов осуществлять в виде строк. Подсчитать количество единичных битов в числе произвольной размерности, представленном в виде массива чисел типа longint (см. задание 3). Ввод чисел осуществить со стандартного ввода в 16-ричном виде. Переставить биты в числе произвольной размерности представленном в виде массива чисел типа longint (см. задание 3) в соответствии с принципом: первый меняется с последним, второй с предпоследним и т. д. Ввод-вывод чисел осуществить через двоичные файлы. Определить является ли заданное 32-х битное число простым. Для массива 32-х битных целых чисел найти разность между максимальным и минимальным элементами. Для массива 32-х битных целых чисел определить количество элементов больших заданного числа, меньших его и равных ему. Для массива 32-х битных целых чисел определить сколько раз меняется знак числа. Отсортировать массив 32-х битных целых чисел все отрицательные элементы перенести в его начало, положительные в конец. Отсортировать массив 32-х битных целых чисел по возрастанию методом пузырька. Определить сколько чисел 32-х битного целого массива находятся в заданном диапазоне.ЛАБОРАТОРНАЯ РАБОТА №7. ВЗАИМОДЕЙСТВИЕ ПРОГРАММ НА ЯЗЫКЕ PASCAL С КОДОМ НАПИСАННЫМ НА ЯЗЫКЕ АССЕМБЛЕРА
Цель и задача работы.
Изучить принципы взаимодействия программ, написанных на высокоуровневом языке типа Паскаль с низкоуровневым кодом на ассемблере на примере 32-битного ассемблера среды Virtual Pascal. Изучить механизмы вызова процедур и функций.
Теоретические положения
При разработке программ на языках высокого уровня всегда следует мыслить в терминах именно высокоуровневых моделей, ставя превыше всего возможную расширяемость и удобство дальнейшего сопровождения исходного кода.
Однако понимание того, во что разворачивается высокоуровневый код после компиляции все-таки полезно. Традиционно в руководствах по ассемблеру приводят аргументы в пользу оптимизации программ путем переписывания части кода на ассемблере. В настоящее время такое использование ассемблера не очень актуально, т. к. современные компиляторы обычно превосходят уровень среднего программиста на ассемблере по таким параметрам как скорость выполнения кода. Но современные компиляторы, как и любые программы, содержат ошибки, которые иногда приводят к неправильной генерации кода. В поиске таких ошибок программисту и может помочь знание ассемблера.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |


