-
Notifications
You must be signed in to change notification settings - Fork 2
Лекция 1
Зубков С. В. “Assembler. Для DOS, Windows и Unix”
Изначально (17-18 века) компьютером называлось не устройство, а профессия вычислителя, выполняющего сложные вычислительные задачи. Только в 19 веке с усложнением вычислительных задач стали появляться вычислительные устройства различных типов (от арифмометров до механических вычислительных машин). В начале 20 века научились делать электрические машины для вычислений, но они также предназначались для решения частных задач, в особенности в военной сфере (разработка проекта атомной бомбы). К середине 20 века назрел вопрос о создании универсальной электронной вычислительной машины, которая могла бы выполнять произвольные алгоритмы без перестраивания самой машины.
- Использование двоичной системы счисления в вычислительных машинах (0 - нет сигнала, 1 - есть сигнал).
- Программное управление ЭВМ.
- Память компьютера используется не только для хранения данных, но и программ.
- Ячейки памяти ЭВМ имеют адреса, которые последовательно пронумерованы (от нуля до максимального значения). Каждый адрес ячейки по сути является переменной, с которой можно работать отдельно.
- Возможность условного перехода в процессе выполнения программы (необходима для реализации сложных алгоритмов, т.к. без неё нельзя было бы строить нелинейные алгоритмы с ветвлениями и т.д.).
- УУ обрабатывает (интерпретирует) и выполняет команды
- АЛУ выполняет арифметические и логические (бинарные) операции над данными
- Процессор взаимодействует с памятью, из которой он берёт данные и программный код и пишет туда некоторые изменяемые значения для работы программы
- Присутствует абстракция ввода и вывода
- Если процессору необходимо считать какое-то значение из памяти, то он выставляет на шину адреса номер ячейки памяти, которую надо считать (её адрес), и отправляет сигнал по шине управления ("Память, читай значение, которое я запросил"). Далее программа прерывается, и идёт ожидание от оперативной памяти. Оперативная память находит запрашиваемую ячейку, считывает из её значение, выставляет его на шину данных и отвечает процессору по шине управления ("Готово, данные установлены"). Центральный процессор получает данные по шине данных и продолжает свою работу. Аналогично выполяется процесс записи в память.
- В центральном процессоре, по сравнению с абстрактной архитектурой фон Неймана, добавляется блок регистров.
- Регистры - внутренние ячейки памяти процессора. В процессоре их немного - до нескольких десятков в современных процессорах. Состоят всего из нескольких байтов (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
Такой принцип адресации позволяет сократить адресные линии (и, соответственно, длину номеров ячеек памяти) и упростить адресацию.
Машинное слово - машинно-зависимая величина, измеряемая в битах, равная разрядности регистров и шины данных.
- 7-битная кодировка (в расширенном варианте - 8-битная)
- первые 32 символа - непечатные (служебные)
- старшие 128 символов 8-битной кодировки - национальные языки, псевдографика и т. п.
- 0, 1, 10, 11, 100, 101…
- 2^8 = 256
- 2^10 = 1024
- 2^16 = 65536
- Суффикс - b. Пример: 1101b
- 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 - “-”).
Возможные способы:
- прямой код
- обратный код (инверсия)
- дополнительный код (инверсия и прибавление единицы)
-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
- Микропроцессор 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 г.
Машинная команда - инструкция (в двоичном коде) из аппаратно определённого набора, которую способен выполнять процессор.
Машинный код - система команд конкретной вычислительной машины, которая интерпретируется непосредственно процессором.
Язык ассемблера - машинно-зависимый язык программирования низкого уровня, команды которого прямо соответствуют машинным командам.
- Исполняемый файл - файл, содержащий программу в виде, в котором она может быть исполнена компьютером (то есть в машинном коде).
- Получение исполняемых файлов обычно включает в себя 2 шага: компиляцию и линковку.
- Компилятор - программа для преобразования исходного текста другой программы на определённом языке в объектный модуль (предполагается, что, как в языке Си, один файл с исходным кодом превращается в один объектный модуль).
- Компоновщик (линковщик, линкер) - программа для связывания нескольких объектных файлов в исполняемый.
- В DOS и Windows - расширения .EXE и .COM
- Последовательность запуска программы операционной системой:
- Определение формата файла.
- Чтение и разбор заголовка.
- Считывание разделов исполняемого модуля (файла) в ОЗУ по необходимым адресам.
- Подготовка к запуску, если требуется (загрузка библиотек).
- Передача управления на точку входа.
- Отладчик - программа для автоматизации процесса отладки. Может выполнять трассировку, отслеживать, устанавливать или изменять значения переменных в процессе выполнения кода, устанавливать или удалять контрольные точки или условия остановки.
- не имеет заголовка;
- состоит из одной секции, не превышающей 64 Кб;
- загружается в ОЗУ без изменений;
- начинает выполняться с 1-го байта (точка входа всегда в начале).
- Система выделяет свободный сегмент памяти нужного размера и заносит его адрес во все сегментные регистры (
CS
,DS
,ES
,FS
,GS
,SS
). - В первые 256 (100h) байт этого сегмента записывается служебная структура DOS, описывающая программу -
PSP
. - Непосредственно за ним загружается содержимое COM-файла без изменений.
- Указатель стека (регистр
SP
) устанавливается на конец сегмента. - В стек записывается 0000h (начало
PSP
- адрес возврата для возможности завершения командойret
). - Управление передаётся по адресу
CS:0100h
.
- Команды пересылки данных
- Арифметические и логические команды
- Команды переходов
- Команды работы с подпрограммами
- Команды управления процессором
- Источник: непосредственный операнд (константа, включённая в машинный код), РОН, сегментный регистр, переменная (ячейка памяти).
- Приёмник: РОН, сегментный регистр, переменная (ячейка памяти).
Правильно:
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
- Передаёт управление в другую точку программы (на другой адрес памяти), не сохраняя какой-либо информации для возврата.
- Операнд - непосредственный адрес (вставленный в машинный код), адрес в регистре или адрес в переменной.
- Ничего не делает
- Занимает место и время
- Размер - 1 байт, код - 90h
- Назначение - задержка выполнения либо заполнение памяти, например, для выравнивания
...
XOR AX, AX
MOV BX, 5
label1:
INC AX
ADD BX, AX
JMP label 1
Прерывания - аппаратный механизм для приостановки выполнения текущей программы и передачи управления специальной программе - обработчику прерывания.
- аппаратные
- программные
int <номер> - вызов (генерация прерывания)
21h - прерывание DOS, предоставляет прикладным программам около 70 различных функций (ввод, вывод, работа с файлами, завершение программы и т.д.)
Номер функции прерыванию 21h передаётся через регистр AH. Параметры для каждой функции передаются собственным способом, он описан в документации. Там же описан способ возврата результата из функции в программу.
Физический адрес получается сложением адреса начала сегмента (на основе сегментного регистра) и смещения.
Сегментный регистр хранит в себе старшие 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]
=> физический адрес:
- SEG необходимо побитово сдвинуть на 4 разряда влево (или умножить на 16, что тождественно)
- К результату прибавить OFFSET
5678h:1234h =>
56780
+ 1234
= 579B4
Распространённые пары регистров: CS:IP
(указатель на следующую команду), DS:BX
(указатель на некоторую переменную), SS:SP
(указатель на вершину стека).
-
Сегмент кода - регистр
CS
. КомандойMOV
изменить невозможно, меняется автоматически по мере выполнения команд. -
Сегмент данных. Основной регистр -
DS
, при необходимости дополнительных сегментов данных задействуютсяES
,FS
,GS
. -
Сегмент стека - регистр
SS
.