- •Глава 1 Введение в семейство персональных компьютеров ibm pc
- •Глава 2 Выполнение программ
- •Глава 3 Требования языка ассемблер
- •Глава 4 Ассемблирование и выполнение программ
- •Глава 5 Определение данных
- •Глава 8 Экранные операции I: Основные свойства
- •Глава 9 Экранные операции II: Расширенные возможности
- •Глава 10 Экранные операции III: Цвет и графика
- •Глава 11 Команды обработки строк
- •Глава 12 Арифметические операции I: Обработка двоичных данных
- •Глава 13 Арифметические операции II:
- •Глава 14 Обработка таблиц
- •Глава 15 Дисковая память I: Организация
- •Глава 16 Дисковая память II: Функции базовой версии dos
- •Глава 17 Дисковая память III: Расширенные функции dos
- •Глава 18 Дисковая память IV: Функции bios
- •Глава 19 Печать
- •Глава 20 Макросредства
- •0000 Csig segment para 'Code'
- •0100 Eb 00 begin: jmp short main
- •0102 Main proc near
- •0109 Main endp
- •0109 Cseg ends
- •20.1. Напишите необходимые директивы: а) для подавления всех команд,
- •04Af в регистр cs. Комбинация этих адресов указывает на первую выполняемую
- •0000 Stacksg segment para stack 'Stack'
- •0000 Codesg segment para 'Code'
- •13D40 плюс 0000. Обратите внимание, что основная программа начинается по
- •0000 Stacksg segment para stack 'Stack'
- •0000 Codesg segment para public 'code'
- •0000 Stacksg segment para stack 'Stack'
- •0000 Codesg segment para public 'code'
- •Ibm Personal Computer Linker
- •0000 Stacksg segment para stack 'Stack'
- •0000 Codesg segment para public 'Code'
- •1. Инициализирующая команда push ds заносит адрес сегмента в стек. Этот
- •010 Clear ,32768!
- •1. Наберите ассемблерную подпрограмму, сохраните ее под именем
- •Ibm Personal Computer Linker
- •Version 2.30 (c) Copyright ibm Corp. 1981, 1985
- •00000H 00011h 00012h codesg code
- •Ibm Personal Computer Basic
- •00 Указатель блока вызывающей программы
00 Указатель блока вызывающей программы
02 Указатель сегмента возврата
04 Указатель смещения возврата
06 Адрес второго параметра
08 Адрес первого параметра
Так как ассемблерная подпрограмма будет использовать регистр BP, то
его необходимо сохранить в стеке для последующего восстановления при
возврате в вызывающую PASCAL-программу. Заметьте, что этот шаг в
вызываемой подпрограмме аналогичен предыдущему примеру на рис.21.6.
Регистр SP обычно адресует элементы стека. Но так как этот регистр
нельзя использовать в качестве индексного регистра, то после сохранения
старого значения регистра BP необходимо переслать адрес из регистра SP в
BP. Этот шаг дает возможность использовать регистр BP в качестве
индексного регистра для доступа к элементам в стеке.
Следующий шаг - получить доступ к адресам двух параметров в стеке.
Первый переданный параметр (адрес строки) находится в стеке по смещению
08, и может быть адресован по BP+08. Второй переданный параметр (адрес
столбца) находится в стеке по смещению 06 и может быть адресован по BP+06.
Два адреса из стека должны быть переданы в один из индексных
регистров BX, DI или SI. В данном примере адрес строки пересылается из
[BP+08] в регистр SI, а затем содержимое из [SI] (значение строки)
пересылается в регистр DH.
Значение столбца пересылается аналогичным способом в регистр DL.
Затем подпрограмма использует значения строки и столбца в регистре DX при
вызове BIOS для установки курсора. При выходе подпрограмма восстанавливает
регистр BP. Команда RET имеет операнд, значение которого в два раза больше
числа параметров, в данном случае 2х2, или 4. Параметры автоматически
выводятся из стека и управление переходит в вызывающую программу.
Если в подпрограмме предстоит изменить сегментный регистр то
необходимо сохранить его значение командой PUSH на входе и восстановить
командой POP на выходе. Можно также использовать стек для передачи величин
из подпрограммы в вызывающую программу. Хотя рассмотренная подпрограмма не
возвращает каких-либо значений, в языке PASCAL предполагается, что
подпрограмма возвращает одно слово в регистре AX или двойное слово в
регистровой паре DX:AX.
В результате компановки двух программ будет построена карта
компановки, в которой первый элемент PASCALL представляет
PASCALL-программу, второй элемент CODESEG (имя сегмента кода) представляет
ассемблерную подпрограмму. Далее следует несколько подпрограмм для
PASCALL-программы. Эта довольно тривиальная программа занимает в
результате шест.5720 байт памяти - более 20К. Компилирующие языки обычно
генерируют объектные коды значительно превышающие по объему размеры
компилируемой программы.
КОМПОНОВКА ПРОГРАММ НА ЯЗЫКЕ CИ И АССЕМБЛЕРЕ
________________________________________________________________
Трудность описания связи программ на языке C и ассемблерных программ
состоит в том, что различные версии языка C имеют разные соглашения о
связях и для более точной информации следует пользоваться руководством по
имеющейся версии языка C. Здесь приведем лишь некоторые соображения,
представляющие интерес:
- Большинство версий языка C обеспечивают передачу параметров
через стек в обратной (по сравнению с другими языками)
последовательности. Обычно доступ, например, к двум параметрам,
передаваемым через стек, осуществляется следующим образом:
MOV ES,BP
MOV BP,SP
MOV DH,[BP+4]
MOV DL,[BP+6]
...
POP BP
RET
- Некоторые версии языка C различают прописные и строчные буквы,
поэтому имя ассемблерного модуля должно быть представлено в том же
символьном регистре, какой используют для ссылки C-программы.
- В некоторых версиях языка C требуется, чтобы ассемблерные
программы, изменяющие регистры DI и SI, записывали их содержимое в
стек при входе и восстанавливали эти значения из стека при выходе.
- Ассемблерные программы должны возвращать значения, если это
необходимо, в регистре AX (одно слово) или в регистровой паре DX:AX
(два слова).
- Для некоторых версий языка C, если ассемблерная программа
устанавливает флаг DF, то она должна сбросить его командой CLD перед
возвратом.
ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ
________________________________________________________________
- В основной программе, вызывающей подпрограмму, необходимо
определять точку вход