Skip to content

Лекция 1

Inspirate789 edited this page Mar 16, 2022 · 6 revisions

Литература.

Зубков С. В. “Assembler. Для DOS, Windows и Unix”

История создания ЭВМ. Появление вычислителей общего назначения. Архитектура фон Неймана.

Изначально (17-18 века) компьютером называлось не устройство, а профессия вычислителя, выполняющего сложные вычислительные задачи. Только в 19 веке с усложнением вычислительных задач стали появляться вычислительные устройства различных типов (от арифмометров до механических вычислительных машин). В начале 20 века научились делать электрические машины для вычислений, но они также предназначались для решения частных задач, в особенности в военной сфере (разработка проекта атомной бомбы). К середине 20 века назрел вопрос о создании универсальной электронной вычислительной машины, которая могла бы выполнять произвольные алгоритмы без перестраивания самой машины.

От решения частных вычислительных задач - к универсальным системам

Принципы фон Неймана (архитектуры фон Неймана):

  1. Использование двоичной системы счисления в вычислительных машинах (0 - нет сигнала, 1 - есть сигнал).
  2. Программное управление ЭВМ.
  3. Память компьютера используется не только для хранения данных, но и программ.
  4. Ячейки памяти ЭВМ имеют адреса, которые последовательно пронумерованы (от нуля до максимального значения). Каждый адрес ячейки по сути является переменной, с которой можно работать отдельно.
  5. Возможность условного перехода в процессе выполнения программы (необходима для реализации сложных алгоритмов, т.к. без неё нельзя было бы строить нелинейные алгоритмы с ветвлениями и т.д.).

pic_01

  • УУ обрабатывает (интерпретирует) и выполняет команды
  • АЛУ выполняет арифметические и логические (бинарные) операции над данными
  • Процессор взаимодействует с памятью, из которой он берёт данные и программный код и пишет туда некоторые изменяемые значения для работы программы
  • Присутствует абстракция ввода и вывода

Структурная схема ЭВМ

pic_02

  • Если процессору необходимо считать какое-то значение из памяти, то он выставляет на шину адреса номер ячейки памяти, которую надо считать (её адрес), и отправляет сигнал по шине управления ("Память, читай значение, которое я запросил"). Далее программа прерывается, и идёт ожидание от оперативной памяти. Оперативная память находит запрашиваемую ячейку, считывает из её значение, выставляет его на шину данных и отвечает процессору по шине управления ("Готово, данные установлены"). Центральный процессор получает данные по шине данных и продолжает свою работу. Аналогично выполяется процесс записи в память.
  • В центральном процессоре, по сравнению с абстрактной архитектурой фон Неймана, добавляется блок регистров.
  • Регистры - внутренние ячейки памяти процессора. В процессоре их немного - до нескольких десятков в современных процессорах. Состоят всего из нескольких байтов (1, 2, 4 или 8 в 64-разрядных процессорах). По сути эти регистры - весь доступный процессору объём ресурсов, необходимый ему для выполнения программ.
  • Процессор тесно взаимодействует с оперативной памятью. Программа обязательно должна быть загружена в оперативную память перед её выполнением.
  • Оперативная память - единственный вид памяти, к которому процессор имеет прямой доступ. Все остальные запоминающие устройства являются внешними.
  • Все устройства должны быть подключены к системной шине.
  • В компьютере функции системной шины по существу выполняет материнская плата.
  • На практике понятие "системная шина" не применяется. Оно заменяется на
    • Быстродействующую шину между процессором и оперативной памятью
    • Шины для подключения внешних устройств (PCI, USB - Universal Serial Bus)
  • Можно сказать, что в компьютере есть много шин, и все они с помощью контроллеров объединяются в единое целое, делая устройства доступными для процессора.

Виды памяти (по убыванию быстродействия):

  • Регистры процессора
  • Кеш-память процессора (на схеме её нет, но во всех современных процессорах она есть). Может быть несколько уровней и нужна для ускорения работы с оперативной памятью или другими устройствами
  • Оперативная память (с помощью неё происходит работа программ, ОС и , по сути, всего компьютера в целом). Очищается при отключении питания.

    Но как же тогда загружать компьютер? Хранить в ПЗУ стартовую программу загрузки компьютера и загружать её в оперативную память при включении питания.

    Процессор при включении питания начинает работать с некоторого фиксированного адреса (зависит от архитектуры). В соответствии с этим материнские платы настраиваются так, чтобы данные из ПЗУ при включении копировались в оперативную память по нужным адресам (или каким-то другим образом отображались туда). Тогда процессор начнёт работать с этой стартовой программы (BIOS - Basic Input/Output System), которая выполняет первичную диагностику устройств (определяет, что подключено) и определяет, готов ли компьютер функционировать. Далее она находит внешнюю память и загрузочный диск и загружает с него ОС.

Память. Единица адресации.

Минимальная адресуемая единица памяти - байт:

  • 1 байт = 8 бит. Именно такая величина байта позволяет в нём хорошо хранить различные данные (числа 0..255 или символы двух алфавитов)
  • 2^8 = 256 значений (0..255)
  • 8 = 2^3
  • 256 = 2^8 = 10h^2 = 100h

Есть битовые операции, но нет возможности считать из памяти отдельный бит или записать его.

Такой принцип адресации позволяет сократить адресные линии (и, соответственно, длину номеров ячеек памяти) и упростить адресацию.

С другой стороны, бит - слишком маленькая единица информации. чтобы с ней отдельно оперировать.

Машинное слово - машинно-зависимая величина, измеряемая в битах, равная разрядности регистров и шины данных.

Параграф - 16 байт

ASCII (аски́) - American standard code for information interchange, США, 1963.

pic_03

  • 7-битная кодировка (в расширенном варианте - 8-битная)
  • первые 32 символа - непечатные (служебные)
  • старшие 128 символов 8-битной кодировки - национальные языки, псевдографика и т. п.

Системы счисления.

Двоичная (binary)

  • 0, 1, 10, 11, 100, 101…
  • 2^8 = 256
  • 2^10 = 1024
  • 2^16 = 65536
  • Суффикс - b. Пример: 1101b

Шестнадцатеричная (hexadecimal)

  • 0, 1, …, 8, 9, A, B, C, D, E, F, 10, 11, 12, …., 19, 1A, 1B, …
  • 2^4 = 1016
  • 2^8 = 10016
  • 2^16 = 1000016
  • Суффикс - h (10h - 16). Некоторые компиляторы требуют префикса 0x

Пример перевода: |1011|0110|1111|1000|b = |B|6|F|8|h

Представление отрицательных чисел.

Знак - в старшем разряде (0 - “+”, 1 - “-”).

Возможные способы:

  • прямой код
  • обратный код (инверсия)
  • дополнительный код (инверсия и прибавление единицы)

Примеры доп. кода на 8-разрядной сетке:

-1:
1.   00000001 - записали число в 8-разрядной сетке
2.   11111110 - инвертировали все разряды
3.   11111111 - прибавили 1

Смысл: -1 + 1 = 0 (хоть и с переполнением): 11111111 + 1 = (1)00000000

-101101:
1.   00101101 - записали число в 8-разрядной сетке
2.   11010010 - инвертировали все разряды
3.   11010011 - прибавили 1

Виды современных архитектур ЭВМ:

  • x86-64 (Эволюция: 8086 (16-разр.) ==> x86 (32-разр.) ==> x86-64 (64-разр.))
  • ARM (устанавливаются в мобильных устройствах)
  • IA64 (мёртвая)
  • MIPS (включая Байкал)
  • Эльбруc

Семейство процессоров x86 и x86-64.

  • Микропроцессор 8086: 16-разрядный, 1978 г., 5-10 МГц, 3000 нм
  • Предшественники: 4004 - 4-битный, 1971 г.; 8008 - 8-битный, 1972 г.; 8080 - 1974 г.
  • Требует микросхем поддержки
  • 80186 - 1982 г., добавлено несколько команд, интегрированы микросхемы поддержки
  • 80286 - 1982 г., 16-разрядный, добавлен защищённый режим
  • 80386, 80486, Pentium, Celeron, AMD, … - 32-разрядные, повышение быстродействия и расширение системы команд
  • x86-64 (x64) - семейство с 64-разрядной архитектурой
  • Отечественный аналог - К1810ВМ86, 1985 г.

Устройство 8086.

pic_04

Архитектура 8086 с точки зрения программиста (структура блока регистров).

pic_05

Регистр IP - указатель следующей команды.

Язык ассемблера.

Машинная команда - инструкция (в двоичном коде) из аппаратно определённого набора, которую способен выполнять процессор.

Машинный код - система команд конкретной вычислительной машины, которая интерпретируется непосредственно процессором.

Язык ассемблера - машинно-зависимый язык программирования низкого уровня, команды которого прямо соответствуют машинным командам.

Исполняемые файлы. Компиляция. Линковка.

  • Исполняемый файл - файл, содержащий программу в виде, в котором она может быть исполнена компьютером (то есть в машинном коде).
  • Получение исполняемых файлов обычно включает в себя 2 шага: компиляцию и линковку.
  • Компилятор - программа для преобразования исходного текста другой программы на определённом языке в объектный модуль (предполагается, что, как в языке Си, один файл с исходным кодом превращается в один объектный модуль).
  • Компоновщик (линковщик, линкер) - программа для связывания нескольких объектных файлов в исполняемый.

Исполняемые файлы. Запуск программы. Отладчик.

  • В DOS и Windows - расширения .EXE и .COM
  • Последовательность запуска программы операционной системой:
    1. Определение формата файла.
    2. Чтение и разбор заголовка.
    3. Считывание разделов исполняемого модуля (файла) в ОЗУ по необходимым адресам.
    4. Подготовка к запуску, если требуется (загрузка библиотек).
    5. Передача управления на точку входа.
  • Отладчик - программа для автоматизации процесса отладки. Может выполнять трассировку, отслеживать, устанавливать или изменять значения переменных в процессе выполнения кода, устанавливать или удалять контрольные точки или условия остановки.

“Простейший” формат исполняемого файла

.COM (command) - простейший формат исполняемых файлов DOS и ранних версий Windows:

  • не имеет заголовка;
  • состоит из одной секции, не превышающей 64 Кб;
  • загружается в ОЗУ без изменений;
  • начинает выполняться с 1-го байта (точка входа всегда в начале).

Последовательность запуска COM-программы:

  1. Система выделяет свободный сегмент памяти нужного размера и заносит его адрес во все сегментные регистры (CS, DS, ES, FS, GS, SS).
  2. В первые 256 (100h) байт этого сегмента записывается служебная структура DOS, описывающая программу - PSP.
  3. Непосредственно за ним загружается содержимое COM-файла без изменений.
  4. Указатель стека (регистр SP) устанавливается на конец сегмента.
  5. В стек записывается 0000h (начало PSP - адрес возврата для возможности завершения командой ret).
  6. Управление передаётся по адресу CS:0100h.

Классификация команд процессора 8086.

  • Команды пересылки данных
  • Арифметические и логические команды
  • Команды переходов
  • Команды работы с подпрограммами
  • Команды управления процессором

Команда пересылки данных MOV.

MOV <приёмник>, <источник>

  • Источник: непосредственный операнд (константа, включённая в машинный код), РОН, сегментный регистр, переменная (ячейка памяти).
  • Приёмник: РОН, сегментный регистр, переменная (ячейка памяти).
Правильно:
MOV AX, 5
MOV BX, DX
MOV [1234h], CH
MOV DS, AX

Неправильно:
MOV [0123h], [2345h] ; нельзя напрямую скопировать переменную в переменную, т.к. процессор может либо что-то считать из памяти (в регистры), либо записать в неё (из регистров)
MOV DS, 1000h        ; в сегментные регистры нельзя напрямую записывать константы, т.е. в сегментные регистры можно записывать значения только из регистров общего назначения

Целочисленная арифметика (основные команды).

  • ADD <приёмник>, <источник> - выполняет арифметическое сложение приёмника и источника. Сумма помещается в приёмник, источник не изменяется.
  • SUB <приёмник>, <источник> - арифметическое вычитание источника из приёмника.
  • MUL <источник> - беззнаковое умножение. Умножаются источник и AL/AX, в зависимости от размера (разрядности) источника (если 1 байт, то AL, а если 2 байта, то на AX). Результат помещается в AX (если 1 байт умножался на 1 байт; то есть предполагается, что результат может быть в 2 раза длиннее аргумента) либо DX:AX (если 2 байта умножались на 2 байта; предполагается, что результат получится 4-байтовым, и его старшие 2 байта помещаются в DX, младшие 2 - в AX).
  • DIV <источник> - целочисленное беззнаковое деление. Делится AL/AX на источник. Результат помещается в AL/AX, остаток - в AH/DX. Выбор регистра опять зависит от разрядности источника (закономерность аналогична умножению).
  • INC <приёмник> - инкремент на 1.
  • DEC <приёмник> - декремент на 1.

Побитовая арифметика (основные команды).

  • AND <приёмник>, <источник> - побитовое “И”.
    AND al, 00001111b
    
  • OR <приёмник>, <источник> - побитовое “ИЛИ”.
    OR al, 00001111b
    
  • XOR <приёмник>, <источник> - побитовое исключающее “ИЛИ”.
    XOR AX, BX
    XOR AX, AX - быстрое зануление
    
  • NOT <приёмник> - инверсия
    NOT AX
    

Команда безусловной передачи управления JMP.

JMP <операнд>

  • Передаёт управление в другую точку программы (на другой адрес памяти), не сохраняя какой-либо информации для возврата.
  • Операнд - непосредственный адрес (вставленный в машинный код), адрес в регистре или адрес в переменной.

Команда NOP (no operation).

  • Ничего не делает
  • Занимает место и время
  • Размер - 1 байт, код - 90h
  • Назначение - задержка выполнения либо заполнение памяти, например, для выравнивания

Пример.

    ...
    XOR AX, AX
    MOV BX, 5
label1:
    INC AX
    ADD BX, AX
    JMP label 1

Как это выглядит в отладчике:

pic_06

Взаимодействие программы с внешней средой (ОС, пользователь, ...).

Для взаимодействия пользователя и ОС, в простейшем случае, используется механизм прерываний.

Прерывания - аппаратный механизм для приостановки выполнения текущей программы и передачи управления специальной программе - обработчику прерывания.

Основные виды:

  • аппаратные
  • программные
int <номер> - вызов (генерация прерывания)

21h - прерывание DOS, предоставляет прикладным программам около 70 различных функций (ввод, вывод, работа с файлами, завершение программы и т.д.)

Номер функции прерыванию 21h передаётся через регистр AH. Параметры для каждой функции передаются собственным способом, он описан в документации. Там же описан способ возврата результата из функции в программу.

Память в реальном режиме работы процессора.

Реальный режим работы - режим совместимости современных процессоров с 8086.

Доступен 1 Мб памяти (220 байт), то есть разрядность шины адреса - 20 разрядов.

Физический адрес получается сложением адреса начала сегмента (на основе сегментного регистра) и смещения.

Сегментный регистр хранит в себе старшие 16 разрядов (из 20) адреса начала сегмента. 4 младших разряда в адресе начала сегмента всегда нулевые. Говорят, что сегментный регистр содержит в себе номер параграфа начала сегмента.

Память в реальном режиме работы процессора - пример.

|     Номер параграфа начала сегмента     |
 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
            |              Смещение               |

[SEG]:[OFFSET] => физический адрес:

  1. SEG необходимо побитово сдвинуть на 4 разряда влево (или умножить на 16, что тождественно)
  2. К результату прибавить OFFSET
5678h:1234h =>
  56780
+  1234
= 579B4

Вычисление физического адреса выполняется процессором аппаратно, без участия программиста.

Распространённые пары регистров: CS:IP (указатель на следующую команду), DS:BX (указатель на некоторую переменную), SS:SP (указатель на вершину стека).

Структура памяти программы. Виды сегментов. Назначение отдельных сегментных регистров

  • Сегмент кода - регистр CS. Командой MOV изменить невозможно, меняется автоматически по мере выполнения команд.
  • Сегмент данных. Основной регистр - DS, при необходимости дополнительных сегментов данных задействуются ES, FS, GS.
  • Сегмент стека - регистр SS.