- •1. Внутренние регистры
- •1.1. Регистры данных
- •1.2. Регистры сегментов
- •1.3. Регистры указателей и индексов
- •1.4. Регистр командного указателя
- •1.5. Флаговый регистр
- •2. Структура и процесс разработки программы на языке ассемблера
- •2.1. Команды
- •2.2. Псевдооператоры
- •2.2.1. Псевдооператор segment
- •2.2.2. Псевдооператор proc
- •2.2.3. Псевдооператор assume
- •2.2.4. Псевдооператор end
- •2.2.5. Псевдооператоры определения данных
- •2.3. Инициализация программы
- •3. Команды пересылки данных
- •3.1. Команда mov
- •3.2. Команды push и рор
- •4. Режимы адресации
- •4.1. Регистровая и непосредственная адресация
- •4.2. Исполнительный адрес
- •4.3. Прямая адресация
- •4.4. Косвенная регистровая адресация
- •4.5. Адресация по базе
- •4.6. Прямая адресация с индексированием
- •4.7. Адресация по базе с индексированием
- •5. Команды передачи управления
- •5.1. Команды call и ret
- •5.2. Команда безусловного перехода jmp
- •5.3. Команды условной передачи управления
- •5.4. Команды управления циклами
- •6. Команды обработки строк
- •6.1. Команды пересылки строк movs, movsb, movsw
- •6.2. Префиксы повторения
- •6.3. Команды сравнения строк. Команда cmps.
- •6.4. Команды сканирования строк
- •6.5. Команды загрузки и сохранения строки
- •7. Взаимодействие языков Си и Ассемблера
- •7.1. Внутренняя структура программы на языке Си для ibm pc
- •7.2. Использование функций на языке Ассемблера
- •7.2.1. Основы взаимодействия языков Си и Ассемблера
- •7.2.2. Передача управления в подпрограмму и обратно
- •7.2.3. Использование глобальных данных
- •7.2.4. Использование аргументов функции
- •7.2.5. Возвращение значения через имя подпрограммы
- •7.2.6. Использование аргументов
- •7.3. Вызов функций на языке Си из программ на языке Ассемблера
- •7.4. Использование локальных данных
- •8. Арифметические команды
- •8.1. Форматы хранения десятичных чисел
- •8.2. Команды сложения
- •8.3. Коррекция результата сложения для bcd-форматов
- •8.4. Команда приращения значения приемника на единицу
- •8.5. Команды вычитания
- •8.6. Коррекция результата вычитания для bcd-форматов
- •8.7. Команда уменьшения содержимого приемника на единицу
- •8.8. Команда обращения знака
- •8.9. Команды умножения
- •8.10. Коррекция результатов умножения
- •8.11. Команды деления
- •8.12. Коррекция результатов деления
- •8.13. Команды расширения знака
- •9. Команды манипулирования битами
- •9.1. Логические команды and, or и xor
- •9.2. Команда логического отрицания nот
- •9.3. Команда проверки test
- •9.4. Команды сдвига и циклического сдвига
- •9.4.1. Команды сдвига
- •9.4.2. Команды циклического сдвига
- •10. Команды работы с флагами
- •10.1. Команды управления флагами
- •10.2. Команды пересылки флагов
- •11. Псевдооператоры определения идентификаторов и операции
- •11.1. Псевдооператоры определения идентификаторов
- •11.2. Операции
- •11.2.1. Арифметические операции
- •11.2.2. Логические операции
- •11.2.3. Операции отношения
- •11.2.4. Операции, возвращающие значения
- •11.2.5. Операции присваивания атрибутов
- •12. Условные псевдооператоры
- •13. Макроопределения
- •13.1. Сравнение макроопределений и процедур
- •13.2. Состав макроопределений
- •13.3. Псевдооператоры макроассемблера
- •13.3.1. Псевдооператор local
- •13.3.2. Псевдооператоры повторения
- •13.3.3. Условные псевдооператоры
- •13.3.4. Псевдооператор eхiтм
- •13.4. Операции в макроопределениях
- •13.5. Задание макроопределений в исходных программах
- •13.5.1. Использование библиотеки макроопределений
- •13.5.2. Указания для задания макроопределений
- •13.5.3. Считывание библиотеки макроопределений в программу
- •13.5.4. Удаление макроопределений
7. Взаимодействие языков Си и Ассемблера
7.1. Внутренняя структура программы на языке Си для ibm pc
Исполняемая программа на языке Си состоит из четырех областей: команд, стека, статических данных и динамических данных.
Область команд содержит машинные команды. Стек используется для временного хранения данных и адресов возврата при вызовах подпрограмм. Область статических данных обеспечивает хранение значений переменных программы. В области динамических данных размещаются уже при исполнении программы дополнительные данные, которые могут понадобиться в процессе ее работы.
В первых версиях компиляторов Си доступная память распределялась так. Перед началом исполнения программы однократно инициировался регистр CS как указатель на начало сегмента команд, а регистры ES, SS и DS инициировались как указатели на начало комбинации областей стека и данных.
Данная модель называется малой (в Борланд Си++ опция "Small").
Из-за фиксированных присваиваний регистрам сегментов в программах нельзя было иметь более 64 Кбайт для команд и 64 Кбайт в сумме для данных и стека.
Такие программы невелики и исполняются быстро, поскольку при их работе не требуются манипуляции с регистрами сегментов. Однако это не позволяет программисту получать доступ ко всем ресурсам компьютера IBM PC.
Более поздние компиляторы языка Си обеспечивают реализацию нескольких моделей распределения памяти. Перечислим модели, которые реализуются большинством из компиляторов.
Модель распределения памяти |
Максимальный размер области команд, байт |
Максимальный размер области данных, байт |
Малая модель |
64К |
64К |
Модель больших кодов |
до 1М |
64К |
Модель больших данных |
64К |
до 1М |
Большая модель |
до 1М |
до 1М |
Под областью данных в табл. подразумевается область динамических данных. Размер области статических данных во всех моделях обычно не превышает 64 Кбайт. Аналогично размер области стека также не превышает 64 Кбайт.
Модель больших кодов в Борланд Си++ задается опцией "Medium" –средняя. В этой модели размер области динамических данных по-прежнему не превышает 64 Кбайт, зато за счет манипулирования регистром CS размер сегмента команд (кодов) программы может составлять до 1 Мбайт.
Модель больших данных в Борланд Си++ задается опцией "Compact" – компактная. В этой модели вследствие манипулирования регистрами сегментов обеспечивается большая область динамических данных, но область команд остается ограниченной.
Большая модель памяти в Борланд Си++ задается опцией "Large" – большая. В этой модели и область команд, и область динамических данных могут расти вплоть до заполнения всей доступной памяти.
Модель распределения памяти задается на стадии компиляции путем указания соответствующих параметров при вызове компилятора языка Си или путем настроек интегрированной среды.
Каждое значение параметра, задающего модель распределения памяти, заставляет компилятор генерировать несколько иные машинные коды.
Если, например, задать модель больших кодов, то это может привести к тому, что компилятор будет генерировать вызовы процедур с атрибутом FAR.
Выбор модели больших данных может заставить компилятор генерировать команды, которые используют 4-байтовые адреса вместо 2-байтовых, как в случае малой модели.
Выбор модели зависит от требуемого приложения. Рекомендуется выбирать наименьшую возможную модель, которая удовлетворяет всем требованиям. Применение больших моделей влечет за собой увеличение размера области команд и замедление работы программы.
