- •Введение
- •Лабораторная работа № 1
- •Цель работы:
- •Контрольные вопросы:
- •Задание к лабораторной работе:
- •Лабораторная работа № 2
- •Цель работы:
- •Цель работы:
- •Задания к лабораторной работе:
- •Лабораторная работа № 3
- •Контрольные вопросы:
- •Задания к лабораторной работе:
- •Лабораторная работа № 4
- •Цель работы:
- •Контрольные вопросы:
- •Задания к лабораторной работе:
- •Лабораторная работа № 5
- •Цель работы:
- •Контрольные вопросы:
- •Задания к лабораторной работе:
- •Лабораторная работа № 6
- •Цель работы:
- •Лабораторная работа № 7
- •Цель работы:
- •Пример программы для ос Linux:
- •Контрольные вопросы:
- •Задания к лабораторной работе
- •Лабораторная работа № 8
- •Цель работы:
- •Пример программы на Ассемблере, использующей Windows api:
- •Контрольные вопросы:
- •Задания к лабораторной работе:
Контрольные вопросы:
1. Что такое ASCIIZ-строка?
2. Как можно задать строку в секции данных программы на ассемблере?
3. Где находятся операнд-источник и операнд-приёмник в строковых командах?
4. Для чего служит флаг направления DF?
5. Для чего предназначена функция MessageBoxA? Какие аргументы ей передаются?
Задания к лабораторной работе:
Во всех заданиях предлагается организовать работу со строками, описанными в секции данных, и вывести результат с помощью MessageBoxA.
Словом называется последовательность алфавитно-цифровых символов, ограниченная с двух сторон пробелами либо началом/концом строки.
Предложением называется последовательность слов, завершающаяся точкой либо концом строки.
Палиндромом называется слово, которое читается одинаково и слева направо, и справа налево.
1. Дана строка, состоящая из алфавитно-цифровых символов и пробелов. Заменить в строке строчные латинские буквы на прописные. Указание – используйте команду xlat.
2. Дана строка, состоящая из алфавитно-цифровых символов и пробелов. Заменить в строке прописные латинские буквы на строчные. Указание – используйте команду xlat.
3. Дана строка, состоящая из алфавитно-цифровых символов и пробелов. Инвертировать порядок знаков в слове.
4. Дана строка, состоящая из алфавитно-цифровых символов и пробелов. Инвертировать порядок слов в строке.
5. Дана строка, состоящая из алфавитно-цифровых символов и пробелов. Вывести слова, являющиеся палиндромами, в одной строке, разделенные пробелом.
6. Дана строка, состоящая из маленьких латинских букв, пробелов и точек. Замените первую букву первого слова в предложении на прописную для всех предложений.
7. Даны две строки. Сравнить их лексикографически. Вывести «больше», если первая строка больше второй, «меньше», если меньше, «равно», если строки идентичны.
8. Дана строка, состоящая из алфавитно-цифровых символов и пробелов. Удалить лидирующие и концевые пробелы. Если слова разделены больше чем одним пробелом, оставить только один пробел.
Лабораторная работа № 6
Организация функций
Цель работы:
Изучить организацию функций на языке Ассемблера, способы передачи параметров в функцию и возврата результатов. Научится реализовывать программы повышенной сложности с помощью функциональной декомпозиции.
Подпрограммой называется поименованная или иным образом идентифицированная часть компьютерной программы, содержащая описание определённого набора действий. Подпрограмма может быть многократно вызвана из разных частей программы. Для оформления и использования подпрограмм в языках программирования существуют специальные синтаксические средства.
Если подпрограмма возвращает некоторое значение как результат своей работы, её называют функцией, если не возвращает – процедурой.
Подпрограммы часто используются для многократного выполнения стереотипных действий над различными данными. Подпрограмма обычно имеет доступ к объектам данных, описанным в основной программе (по крайней мере, к некоторым из них), поэтому для того, чтобы передать в подпрограмму обрабатываемые данные, их достаточно присвоить, например, глобальным переменным. Но такой путь не особенно удобен и чреват ошибками.
Для обеспечения контролируемой передачи параметров в подпрограмму и возврата результатов из неё используется механизм параметров. В языках высокого уровня параметры описываются при описании подпрограммы (в её заголовке) и могут использоваться внутри процедуры аналогично переменным, описанным в ней. При вызове процедуры значения каждого из параметров указываются в команде вызова (обычно после имени вызываемой подпрограммы).
В Ассемблере организация передачи параметров подпрограмме осуществляется вручную. Существуют следующие способы передачи параметров в функцию:
1. Через регистры. При этом в описании функции оговаривается, какой регистр какой параметр содержит. Перед вызовом параметры загружаются в соответствующие регистры, затем извлекаются оттуда подпрограммой. Если регистры содержали промежуточные данные, их необходимо сохранить, например в стеке. Так реализованы, например, системные вызовы Linux.
2. Через общую область секции данных. Может применяться только при вызове функций в пределах одной программы. Не очень удобный способ.
3. Через стек. Этот способ очень широко применяется различными компиляторами языков высокого уровня.
При передаче параметров через стек необходимо оговорить два вопроса:
1. В каком порядке аргументы помещаются в стек. Их можно помещать либо начиная с первого, заканчивая последним (прямой порядок аргументов); либо начиная с первого, заканчивая последним (обратный порядок аргументов). Предпочтительным является обратный порядок аргументов, т.к. он позволяет легко реализовать функции, где число и размер операндов зависят от первого операнда (например, printf).
2. Какой код очищает стек. Это может делать либо код процедуры (вызываемый код) с помощью команды ret n; либо код основной программы (вызывающий код) с помощью команды add esp,n. Когда стек чистит вызывающий код, это приводит к тому, что каждый вызов функции сопровождается командой очистки стека. Если же стек очищает вызываемый код, то команда очистки стека будет только одна, и код получится более компактным.
Различные варианты передачи параметров через стек представлены в таблице 4.1.
Таблица 4.1. Варианты передачи параметров через стек
Имя |
Порядок помещения аргументов в стек |
Какой код очищает стек |
c |
обратный |
вызывающий |
pascal |
прямой |
вызываемый |
stdcall |
обратный |
вызываемый |
Пример передачи параметров через стек stdcall-функции:
push param_n
…
push param_2
push param_1
call stdcall_func
Возврат значения функцией обычно организован через регистр. Например, стандарт stdcall предполагает, что возвращаемое значение будет находится в регистре eax.
При написании функции, работающей с параметрами через стек, очень удобно сохранить адрес, с которого начинаются параметры, в регистре указателя кадра стека (ebp). Пример (предполагается, что параметры и локальные переменные имеют размер двойное слово):
mov ebp,esp
mov eax,[ebp+4] ;Загрузка параметра №1
mov ebx,[ebp+8] ;Загрузка параметра №2
Таким образом можно легко работать с параметрами, и при этом выделять место в стеке под локальные переменные. К ним можно обращаться тем же способом:
mov ecx,[ebp-4] ;Чтение первой локальной переменной
mov edx,[ebp-8] ;Чтение второй локальной переменной
При этом перед работой с локальными переменными необходимо выделить под них место командой
sub esp, размер_переменных
а после работы – очистить стек командой
add esp, размер_переменных
В языке Ассемблера подпрограмма может никак не оформляться – достаточно описать метку, по которой будет происходить переход на подпрограмму. Однако, в синтаксисе предусмотрена специальная конструкция для описания подпрограмм:
имя_процедуры proc
.... ;команды процедуры
имя_процедуры endp
Процедуры можно разместить до текста основной программы или после него – это не имеет особого значения. Можно даже поместить процедуру посреди кода основной программы, но тогда её придётся «обходить» командой jmp.
Если код подпрограммы находится в одном исходном файле, а вызывающий код – в другом, то в таком случае необходимо дать указания транслятору, чтобы он включил в объектные файлы специальную информацию для компоновщика. Это можно сделать с помощью директив public и extrn. В модуле, в котором находится код процедуры, необходимо объявить её директивой public:
public my_proc
А в вызывающем модуле объявить эту метку как внешнюю:
extrn my_proc
После этого можно будет откомпилировать исходные файлы по отдельности и объединить объектные файлы с помощью компоновщика.
Контрольные вопросы:
1. Что такое подпрограмма? Для чего нужны подпрограммы?
2. Какие вы знаете способы передачи параметров в функцию?
3. Какой командой может выполнить очистку стека вызывающий код? вызываемый код?
3. Как можно эффективно организовать работу с параметрами, переданными в стеке?
4. Как можно поместить код подпрограммы и вызывающий код в разные исходные файлы?
Задания к лабораторной работе:
Во всех заданиях предполагается разработка программы, состоящей из основной части и одной или нескольких подпрограмм. В отчёте необходимо для каждой подпрограммы указать её название, назначение, перечень передаваемых и возвращаемых значений, алгоритм работы.
Передавать параметры функциям необходимо через регистры или через стек. При этом при передаче через регистры необходимо указать, в каком из регистров какой параметр находится; а при передаче через стек – в каком порядке параметры помещаются в стек, и кто производит его очистку.
1. Разработать программу, находящую минимальную строку из набора строк (в лексикографическом смысле). Указание: разработать функцию, производящую лексикографическое сравнение двух строк.
2. Разработать программу, находящую максимальную строку из набора строк (в лексикографическом смысле). Указание: разработать функцию, производящую лексикографическое сравнение двух строк.
3. Разработать программу, выводящую на экран содержимое двойного слова в шестнадцатеричном виде с помощью MessageBoxA. Указание: разработать функцию, преобразующую отдельный байт.
4. Разработать программу, переводящую строковое представление шестнадцатеричного числа в двоичное. Строка задана в виде константы. Указание: разработать функцию, преобразующую пару шестнадцатеричных цифр в отдельный байт.
5. Разработать программу, получающую целочисленные длины трёх отрезков, и выводящую с помощью MessageBoxA «Да», если из них можно составить треугольник, и нет, если нельзя. Указание: разработать процедуру, проверяющую, превосходит ли сумма двух чисел третье число.
6. Задана замкнутая ломаная без самопересечений. Проверить, является ли она выпуклым многоугольником. Указание: разработать функцию, проверяющую, по какую сторону отрезка лежит точка.
7. Разработать программу, разбивающую строку на слова, и выводящую только слова, являющиеся палиндромами. Указание: разработать две подпрограммы, одна из которых разбивает строку на две части – первое слово и остаток строки, вторая – проверяет, является ли строка палиндромом.
8. Напишите программу, реализующую пирамидальную сортировку (heapsort) двойных слов со знаком. Указание: разработайте процедуру, выполняющую пропихивание («pushdown») элемента в пирамиду.
