Перейти к основному содержанию
EDU-MMCS
Вы используете гостевой доступ (Вход)

CS221. Архитектура компьютера и операционные системы

  1. В начало
  2. Курсы
  3. Осенний семестр
  4. Фундаментальная информатика и ИТ
  5. CS221 CA&OS
  6. Материалы лабораторных работ
  7. Лабораторная №1. Введение. Арифметика. Циклы LOOP ...

Лабораторная №1. Введение. Арифметика. Циклы LOOP [2 балла]

Требуемые условия завершения
Открыто с: воскресенье, 7 сентября 2025, 08:00
Срок сдачи: пятница, 12 сентября 2025, 11:25

1.  Структура программы на языке ассемблера Intel 8088 

Структура программы на языке ассемблера  выглядит следующим образом:

.SECT .TEXT
! <последовательность инструкций процессора>
.SECT .DATA
! <последовательность команд ассемблера выделения памяти с инициализацией>
.SECT .BSS
! <последовательность команд выделения памяти без инициализации>

Последние две секции могут быть пустыми, но заголовки всё равно должны присутствовать. Первая секция предназначена для написания кода (инструкций процессору), вторые две — для хранения статических данных, это полный аналог глобальных переменных в высокоуровневых языках программирования (например, C).

Пример последовательности инструкций для сложения двух чисел 2 и 3:

MOV    AX, 2
ADD    AX, 3

Сначала в регистр AX помещается (командой MOV) двойка (регистрами называется быстрые именованные элементы памяти на процессоре, куда помещаются операнды). Затем к содержимому AX добавляется тройка. Смысл инструкций MOV и ADD легко запомнить, если применять следующую мнемонику: большинство арифметических инструкций аналогичны присваивающим формам арифметических операций в C (в частном случае, MOV аналогичен операции присваивания). То есть код выше можно было бы перевести на C следующим образом (считая AX обычной переменной):

AX =  2
AX += 3

Попробуйте сассемблировать (с помощью as88) и выполнить по шагам (с помощью t88) программу, приведённую выше. Для этого нужно создать текстовый файл (назовём его task-0.s) с объявлением всех трёх секций и с двумя указанными инструкциями в секции кода. А затем выполнить

as88 task-0.s && t88 task-0.s

в терминале (он запускается командой Ctrl+Alt+T). Если ассемблирование (команда as88) пройдёт без ошибок, то запустится отладка (t88). В ходе отладки проследите изменение значений регистра AX. После выполнения обеих инструкций (клавиша Enter) и проверки значения регистра AX завершите работу отладчика командой q.

Замечание по оформлению кода: правило «четырёх столбцов». Код рекомендуется оформлять в 4 столбца: столбец меток, столбец инструкций и команд ассемблера, столбец операндов, комментарии. Это правило используется, даже если столбец пуст (например, первая колонка с метками почти всегда пуста и потому инструкции пишутся с отступом). Исключением являются начала секций — директива .SECT пишется без отступа. Столбцы разделяются достаточным для визуального восприятия количеством нажатий Tab (1 или 2 в зависимости от настроек редактора), желательно, чтобы визуально это соответствовало 8 пробелам. Между секциями следует оставлять пустые строки.

Помните, что выполнение требований по оформлению и именованию файлов оценивается.

Замечание об эффективной работе с инструментами. На странице с описанием утилит ассемблирования кратко описано, как лучше всего работать с текстами программ и выполнять их запуск. В частности, там предлагается скачать два вспомогательных сценария — рекомендуется сделать это прямо сейчас.

2.  Режимы адресации

Под термином режимы адресации в языках ассемблеров понимается способ передачи («адресация») операндов инструкций, перечислим основные из этих способов.

  1. Непосредственная адресация («непосредственные операнды») — операнд передаётся процессору прямо вместе с инструкцией. Как 2 и 3 в примере выше.

  2. Регистровая адресация — операнд находится в указанном регистре процессора (пока мы использовали один регистр — AX).

  3. Прямая адресация в памяти — операнды располагаются в оперативной памяти (в наших примерах чаще всего — в сегменте данных) по известному на этапе ассемблирования адресу. Такой адрес обычно задаётся с помощью символического имени: «метки». Ниже приводится соответствующий пример.

    .SECT .TEXT
            MOV     AX, (x)
            ADD     AX, (y)
    
    .SECT .DATA
    x:     .WORD    2
    y:     .WORD    3
    
    .SECT .BSS

В данном примере суммируемые значения размещены в сегменте данных по меткам x и y. Метка отделяется от команды двоеточием. Метка очень похожа на константный указатель C++: она представляет адрес нужного значения (в примере x это адрес значения 2, y это адрес значения 3. Для обращения по этому адресу используется запись (x), (y) и т. п. (аналогично операции разыменования указателя * в C). Часто, для краткости, метки наподобие x и y называют «переменными», хотя это не полностью отражает их смысл.

  1. [task-1.s, вычитание] [0.25 балла] Создайте программу, которая вычитает из числа 3 число 2 по аналогии с примером выше (числа размещены в сегменте данных). Инструкция вычитания SUB получает операнды полностью аналогично ADD.

  2. [task-2.s, запись результата] [0.25 балла] Добавьте в предыдущую программу (используйте команду текстового редактора «Сохранить как…» из меню «Файл») к переменным x и y переменную res. Поскольку у res нет исходного значения, её разумно поместить в секции неинициализированных данных BSS. В этой секции вместо команды .WORD следует использовать команду .SPACE, после которой указывается количество байт под переменную. Все целочисленные значения имеют размер 2 байта.

    После получения результата в регистре AX скопируйте содержимое AX в res с помощью инструкции MOV. Чтобы следить в отладчике за изменением памяти по метке res, можно использовать команду:

    /res

    (её нужно ввести после запуска t88).

3.  Простейшие арифметические команды
  1. [task-3.s, умножение] [0,5 балла] Инструкция умножения MUL имеет отличный от ADD и SUB интерфейс. Она имеет один (явный) операнд, он играет роль одного из сомножителей. Второй сомножитель берётся этой инструкцией (неявно) из регистра AX. Результат умножения может не поместиться в один регистр, потому для него используется пара регистров: младшие 16 бит результата помещаются в регистр AX, старшие — в DX. На занятиях мы будем работать с маленькими числами, потому регистр DX нас волновать не будет, однако такое устройство инструкции MUL может приводить к проблемам, если в регистре DX хранится некая полезная информация — после выполнения MUL она непременно затрётся (если результат умножения положителен и поместился в 16 бит, то в DX попадут нули). А потому программист должен сохранить полезную информацию из DX в каком-либо месте перед использованием MUL — в переменной или в другом регистре.

    Следуя данному описанию составьте программу, которая перемножает два числа, 2 и 3, заданные в сегменте данных, и помещает результат в переменную res, объявленную в секции BSS.

  2. [task-4.s, целочисленное деление]  [0,5 балла]  Инструкция целочисленного деления DIV имеет аналогичный MUL интерфейс. Так же используется один явный параметр, играющий роль делителя. Делимое считается 32-битным и берётся из пары регистров DX:AX (старшие биты в DX). Если делимое помещается в 16 бит, то его нужно загрузить в регистр AX, а в DX забивается 1-битами, если делимое отрицательно и 0-битами в противном случае (такая операция называется знаковым расширением). Для этого непосредственно перед использованием инструкции DIV следует передать инструкцию CWD (Convert Word to Doubleword) без операндов. Вновь следует помнить о том, что хранившаяся в DX информация будет утеряна.

    Частное от деления помещается в регистр AX, а остаток от целочисленного деления — в DX.

    Следуя данному описанию, составьте программу, которая вычисляет сумму: 55 / 10 + 55 % 10 и помещает результат в переменную res, объявленную в секции BSS. (Здесь и далее / означает целочисленное деление, а % — остаток от целочисленного деления).

  3. [task-5.s простейший цикл с LOOP]  [0,5 балла] Для организации циклов используются метки в сегменте кода и специальные инструкции перехода по этим меткам. Простейшая из таких инструкций — LOOP:

            MOV     CX, (n)     ! количество итераций цикла загружаем в CX —
                                !   это требование LOOP
    L1:     ADD     AX, (x)
            LOOP    L1          ! на каждом шаге уменьшает CX на 1, и если CX не равен 0,
                                !   то переходит по метке L1

    этот код (n) раз прибавляет к AX значение (x) (предполагается, что n и x это метки из сегмента данных, указывающие на некоторые числа).

    Следуя данному описанию составьте программу, которая считает сумму 5 + 10 + 15 + 20 + 25. Очередное слагаемое удобно хранить в отдельном регистре (например, BX) и увеличивать его на 5 на каждом шаге цикла.

4.  Дополнительное задание [1 балл]
  1. [task-6.s] Вычислите значение многочлена 2x6 - 3x4 - 5x2+ x - 5 в точке x = 3 (задано в сегменте данных). Указание: четвёртая степень x должна вычисляться с помощью возведения в квадрат второй.


Помощь в подготовке к занятию (видео прошлого года)


◄ Форум для обсуждения курса
Утилиты ассемблирования программ для Intel 8088 (архив для Linux) ►
Пропустить Навигация
Навигация
  • В начало

    • Страницы сайта

      • Мои курсы

      • Теги

    • Мои курсы

    • Курсы

      • Осенний семестр

        • Прикладная математика и информатика

        • Фундаментальная информатика и ИТ

          • Probability Theory and Mathematical Statistics

          • Научные Вычислительные Пакеты

          • DataSc101

          • NLP (7 семестр)

          • Compiler Development

          • CMVSM

          • АЗПК

          • Frontend

          • ТеорЯП

          • Ruby Eng

          • EngCA&OS

          • CS221 CA&OS

            • Общая информация

            • Материалы лабораторных работ

              • СтраницаПодготовка №1. Установка ПО.

              • ЗаданиеЛабораторная №1. Введение. Арифметика. Циклы LOOP ...

              • СтраницаПодготовка №2. Массивы. Условные и безусловные пер...

              • ЗаданиеЛабораторная №2. Массивы. Условные и безусловные п...

              • ЗаданиеПодготовка №3. Интерфейс системных вызовов. Просте...

              • ЗаданиеЛабораторная №3. Интерфейс системных вызовов. Прос...

            • Дистрибутивы и справочная информация

            • Доборы

        • Математика, механика

        • Педагогическое образование

        • Магистратура

          • Разработка мобильных приложений и компьютерных игр

        • Аспирантура

        • Вечернее отделение

        • Другое

        • ФИиТ eng 2025

      • Весенний семестр

        • Прикладная математика и информатика

        • Фундаментальная информатика и ИТ

        • Математика, механика

        • Педагогическое образование

        • Магистратура

          • Разработка мобильных приложений и компьютерных игр

        • Аспирантура

        • Вечернее отделение

        • Другое

      • Воскресная компьютерная школа

        • Пользователь компьютера плюс

        • Пользователь прикладных программ

        • Программирование I ступень

        • Программирование II ступень

        • Программирование III ступень

        • Архив

      • Воскресная математическая школа

        • Открытое тестирование РНОМЦ и мехмата ЮФУ - 2025

        • Олимпиадная математическая школа

        • Повышение квалификации

        • Доступная математика

        • Лаборатория математического онлайн-образования мех...

        • Осенняя универсиада

        • Научно-практическая конференция

        • ВМШ

          • ВМШ - 24

        • Летняя олимпиадная математическая школа РНОМЦ и ме...

      • Государственная итоговая аттестация

      • Дополнительное образование

      • Олимпиады

      • Видеолекции

      • Разное

      • Архив курсов

      • Заочная школа мехмата ЮФУ

Служба поддержки сайта
Вы используете гостевой доступ (Вход)
CS221 CA&OS
Сводка хранения данных
Скачать мобильное приложение Яндекс.Метрика