ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 03.05.2024
Просмотров: 9
Скачиваний: 0
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
МИНОБРНАУКИ РОССИИ
Федеральное государственное бюджетное образовательное учреждение
высшего образования
«Пензенский государственный технологический университет»
(ПензГТУ)
Факультет автоматизированных информационных технологий
Кафедра «Программирование»
Отчет
О ВЫПОЛНЕНИИ ЛАБОРАТОРНОЙ РАБОТЫ № 1
«Линейная программа»
Выполнил: студент
гр. 22ИВ1бз Гимадулин К.И.
Принял: ассистент кафедры «Программирование» Зоткина А.А./ к.т.н., доцент кафедры «Программирование» Данилов Е.А.
г. Пенза, 2022 г.
Лабораторная работа 1
Тема: Линейная программа
Цель работы: изучение основных операций пересылки данных и операций
двоичной арифметики, приобретение навыков программирования вычислений простейших арифметических выражений.
Лабораторное задание. Разработать программу вычисления функции
y = f( a, b, c, d, e). Формат данных – двойное слово.
Методические указания. Значения аргументов a, b, c, d, e задать в программе.
Результат y в память. Правильность результата проверить с помощью программы отладчика. В процессе отладки использовать несколько тестовых наборов исходных данных, в комплексе обеспечивающих исполнение операций, как с положительными, так и с отрицательными числами. Результаты отладки зафиксировать в файле протокола.
Вариант задания:
3) y=a+b*c-d/e
Листинг программы:
#include
#include
#include
using namespace std;
int main()
{
int a, b, c, d, e, y;
cout << "Enter next values: a,b,c,d,e" << endl;
cin >> a >> b >> c >> d >> e;
y = 0;
__asm
{
mov eax, b;
mov ebx, c;
cdq; // расширяем 32 бита до 64 бит
imul ebx; // умножаем b на c
push eax; // записываем в стек
mov eax, d;
mov ebx, e;
idiv ebx; // делим d на e
push eax; // записываем в стек полученное значение
mov eax, a;
pop ebx; // вытягиваем из стека значение b*c
pop ecx; // вытягиваем из стека значение d/e
add eax, ecx; // складываем
sub eax, ebx; // вычитаем
mov y, eax; // записываем в переменную y результат
}
cout << "Result: " << y << endl;
system("pause");
return 0;
}
Тестирование
Для тестирования и отладки использованы тестовые наборы:
Исходные данные | Ожидаемый результат | Фактический результат | Статус | ||||||
a | b | c | d | e | |||||
2 | 4 | 2 | 1 | 5 | 10 | | Пройден | ||
-4 | 2 | 4 | 9 | -9 | 5 | | Пройден | ||
0 | 12 | 3 | 15 | 3 | 31 | | Пройден | ||
-9 | -12 | -3 | 9 | 3 | 24 | | Пройден |
Отладка:
Д
ля просмотра регистров использовал окно отладчика «Регистры».
Для просмотра переменных использовал окно «Локальные переменные».
Контрольные вопросы:
1. Укажите недопустимые сочетания операндов команды mov.
MOV cell, [AX] ; Ошибка - обращение к памяти
MOV DS,0ABCDh – ошибка загрузки константы в сегментный регистр
MOV DS,ES – ошибка передачи данных между сегментными регистрами
MOV CS, AX – ошибка передачи данных в регистр передачи управления
2. Поясните логику выполнения операций push и pop.
Команда PUSH уменьшает значение регистра стека на размер операнда (2 или 4) и копирует содержимое операнда в память по адресу SS:SP.
Команда POP копирует содержимое ячейки памяти по адресу SS:SP в операнд и увеличивает значение регистра стека на размер операнда (2 или 4).
Если операнд использует регистр SP для косвенной адресации, команда POP вычисляет адрес уже после того, как она увеличивает SP.
Если команда выполняется в 32-разрядном режиме, то используется регистр ESP.
С помощью команды POP нельзя загрузить из стека сегментный регистр CS.
3. Какие регистры можно использовать при выполнении арифметических операций?
Следующие регистры можно использовать для арифметических операции:
AL, CL, DL, BL, AH, CH, DH и BH.
AX, CX, DX, BX, SP, BP, SI и DI.
EAX, ECX, EDX, EBX, ESP, EBP, ESI и EDI.
4. Какие арифметические операции применимы как к знаковым, так и к беззнаковым данным?
ADD – сложение
ADC – сложение с переносом
SUB – вычитание
SBB – вычитание с переносом
INC – инкремент
DEC – декремент
CMP – сравнение
5. Поясните схему выполнения операции умножения.
Умножение выполняется командой mul. Она имеет следующую запись:
mul src – источник умножается на значение аккумулятора (AL,AX,EAX)
Для разных размеров операндов логика одинакова, однако имеются различия в размерах регистров:
-
однобайтный операнд r/m8 умножается на значение в регистре AL, результат помещается в регистр AX, флаги CF и OF сбрасываются, если результирующее значение в регистре AH равно нулю, иначе — устанавливаются в 1; -
двухбайтный операнд r/m16 умножается на значение в регистре AX, результат помещается в пару регистров DX:AX, регистр DX содержит старшие 16 бит результата, флаги CF и OF сбрасываются, если результирующее значение в регистре DX равно нулю, иначе — устанавливаются в 1. -
четырехбайтный операнд r/m32 умножается на значение в регистре EAX, результат помещается в пару регистров EDX:EAX, регистр EDX содержит старшие 32 бита результата, флаги CF и OF сбрасываются, если результирующее значение в регистре EDX равно нулю, иначе — устанавливаются в 1.
Существует команда imul, выполняющая знаковое умножение. Формы записи этой команды следующие:
imul src – источник умножается на значение аккумулятора (AL,AX,EAX)
mul dest, src – источник умножается на операнд-назначение и туда же записывается результат
mul dest, src1, src2 – два источника перемножаются между собой и результат записывается в dest.
6. Поясните схему выполнения операции деления.
Деление выполняется с помощью команды div.
Единственный явный операнд команды — операнд-источник (SRC), задающий делитель — может быть переменной в регистре или в памяти (r/m8, r/m16, r/m32). Целая часть частного помещается в регистр AL, AX или EAX в зависимости от заданного размера делителя (8, 16 или 32 бита). При этом остаток от целочисленного деления помещается в регистр AH, DX или EDX соответственно.
Существует команда idiv, выполняющая знаковое деление.
Дополнительной особенностью команд DIV и IDIV является неопределенное значение большинства флагов в регистре EFLAGS в результате выполнения команды. То есть флаги не устанавливаются в соответствии с полученным частным или остатком.
7. Какие подготовительные действия следует выполнить для операции деления?
Для операции деления необходимо увеличить разрядность делителя, используя команды cbw или cwd до команды div или idiv. Это позволит избежать проблем с переполнением.
8. В каких случаях имеет место прерывание при делении?
При делении возможно прерывание, если частное не вместилось в регистр назначения или выполняется деление на ноль.
Вывод: в результате выполнения лабораторной работы была достигнута следующая цель:
Изучены основные операции пересылки данных и операций двоичной арифметики, приобретены навыки программирования вычислений простейших арифметических выражений.