- •Системное программное обеспечение
- •Isbn 978-5-8149-2441-4
- •Введение
- •1. Основы программирования на ассемблере
- •1.1. Принципы построения ассемблерных программ
- •1.2. Понятие архитектуры компьютера
- •1.3. Регистры программиста в ia32
- •1.4. Описание сегментной структуры программы
- •2. Простейшие средства ассемблера
- •2.1. Средства описания данных
- •2.2. Обращения к функциям операционной системы посредством прерываний
- •2.3. Средства преобразования в исполняемый файл
- •2.4. Управление строками при выводе и вводе данных
- •2.5. Простейшие способы адресации
- •3. Архитектурные элементы для построения программ
- •3.1. Организация условных переходов
- •Команды условных переходов
- •3.2. Средства организации циклов
- •3.3. Особенности команд умножения и деления
- •3.4. Организация процедур
- •3.5. Неарифметические операции над кодами
- •3.6. Архитектура amd64 процессоров в ассемблерных Linux программах
- •4. Использование неэлементарных способов адресации
- •4.1. Косвенно-регистровая адресация и ее использование
- •4.2. Использование индексной адресации данных
- •4.3. Базовая и индексно-базовая адресации
- •5. Взаимодействие программных компонентов
- •5.1. Многомодульная разработка программ
- •5.2. Организация стекового кадра подпрограммы
- •5.3. Программный доступ к системным функциям Win32
- •5.4. Использование свободно распространяемых утилит для Win32
- •5.5. Вызов функций из стандартных библиотек Linux
- •6. Библиотеки объектных модулей
- •6.1. Использование библиотек объектных модулей в Linux
- •6.2. Использование библиотек объектных модулей в Win32
- •7. Разделяемые библиотеки выполняемых программ
- •7.1. Понятие о статической и динамической компоновке
- •7.2. Конструкция библиотеки динамической компоновки
- •7.3. Компоновка времени загрузки с использованием GoLink
- •Контрольные вопросы
- •Заключение
- •Библиографический список
1.3. Регистры программиста в ia32
Изучение любого вопроса требует конкретной практической базы, позволяющей демонстрировать на частных примерах общие конструкции и методы, выполнять упражнения, а в данном случае также разрабатывать и исследовать конкретные программы. На момент написания пособия наиболее распространены компьютеры, являющиеся потомками компьютеров IBM PC и основанные на процессорах фирмы Intel. Все они используются в режиме 32-битной обработки данных. Соответствующая архитектура для краткости обозначается IA32. Именно она взята в качестве практической базы дальнейшего изучения программирования на ассемблере.
Полное описание этой архитектуры занимает сотни страниц самого лаконичного текста, поэтому для его детального изложения следует обратиться к технической документации. Здесь же будет приведена минимальная информация, без которой невозможно дальнейшее изложение частных вопросов системного программирования.
Множество регистров программиста в архитектуре IA32 разделяется на регистры общего назначения, обозначаемые мнемониками EAX, EBX, ECX, EDX, регистры указателей и индексов с обозначениями ESI, EDI, EBP, ESP, регистр признаков (флажков) EFlags, регистр указателя команд EIP и сегментные регистры. Все эти регистры, кроме сегментных, 32-бит-ные. Причем все перечисленные регистры, кроме сегментных, могут использоваться и частично, а именно могут применяться только их младшие половины. Эти половины обозначаются соответственно AX, BX, CX, DX, SI, DI, BP, SP, Flags, IP. Младшие половины 16-битных регистров общего назначения могут к тому же использоваться по частям – по составляющим байтам. Именно старшие половины этих частей обозначаются соответственно AH, BH, CH, DH (от англ. слова High), младшие – AL, BL, CL, DL (от англ. слова Low). Происхождение наименования регистров восходит к названию их основной программной функции: AX – аккумулятор (accumulator – накапливающий – основной регистр), BX – базовый (base register), CX – регистр счетчика (counter), DX – регистр данных (data). (Второй символ наименования в обозначении регистров общего назначения появился из английского слова eXtented в связи с тем, что эти регистры исторически являются расширением регистров A, B, C, D архитектуры отдаленного предшественника IA32 – микропроцессоров I80.) Мнемоника DI расшифровывается как Distignation Index (индекс назначения), SI – Source Index (индекс источника). Регистры BP и SP являются аббревиатурой Base Pointer и Stack Pointer, а IP – Instruction Pointer. Заметим, что 16-битная разрядность сегментных регистров сохранена и в архитектуре I32, в которой все остальные регистры обязательно 32-битные.
Отличительной особенностью архитектуры IA32 является специализация регистров общего назначения – ситуация, практически не имеющая аналогов в конкурирующих семействах и связанная с прямой преемственностью базового процессора I86 по отношению к процессору I80, а также со стремлением разработчиков аппаратуры из фирмы Intel в условиях технических ограничений конца 70-х годов реализовать в нем возможно большее число функций. (Всего в процессоре I8086 было около 29000 транзисторов.)
Регистр EAX является наиболее универсальным. Некоторые операции выполняются только с операндами, находящимися в EAX. Предшественник регистра EBX – регистр BX – служил в прежней архитектуре в основном для хранения базового адреса массива или структуры данных (относительно начала сегмента), но мог использоваться и для непосредственного хранения операндов, например при сложении. Регистр ECX наиболее специализирован и во многих случаях изменяется в результате побочного эффекта при выполнении команд, машинный код которых не содержит указания на этот регистр; используется в основном как счетчик в циклах с параметром, который по умолчанию хранится в этом регистре. Многие команды в конце своего выполнения уменьшают значение этого счетчика (регистра) на 1 или 2. Специализированные функции регистров EDI, ESI, EBP и ESP будут описаны позже.
С учетом перспектив неизбежного в будущем перехода на другую архитектуру процессора следует подчеркнуть, что специализация регистров, скорее, исключение, чем правило. Чаще всего в других архитектурах процессоров имелось от 8 до 16 регистров общего назначения, хотя в ряде архитектур один-два из них зарезервированы за указателем команд и указателем стека. Иногда основные регистры делят на две части: регистры данных и адресные регистры, из которых только вторые могут использоваться при построении сложных способов адресации, а первые – лишь содержать данные.