- •Глава 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 Указатель блока вызывающей программы
0000 Stacksg segment para stack 'Stack'
0000 40 [ ???? ] DW 64 DUP(?)
0080 STACKSG ENDS
;-----------------------------------------------
0000 DATASG SEGMENT PARA 'Data'
0000 0140 QTY DW 0140H
0002 2500 PRICE DW 2500H
0004 DATASG ENDS
;-----------------------------------------------
0000 CODESG SEGMENT PARA 'Code'
0000 BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
0000 1E PUSH DS
0001 2B C0 SUB AX,AX
0003 50 PUSH AX
0004 B8 ---- R MOV AX,DATASG
0007 8E D8 MOV DS,AX
0009 A1 0002 R MOV AX,PRICE ;Загрузить стоимость
000C 8B 1E 0000 R MOV BX,QTY ; и количество
0010 9A 0000 ---- E CALL SUBMUL ;Вызвать подпрограмму
0015 CB RET
0016 BEGIN ENDP
0016 CODESG ENDS
END BEGIN
Segments and Groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 0016 PARA NONE 'CODE'
DATASG . . . . . . . . . . . . 0004 PARA NONE 'DATA'
STACKSG. . . . . . . . . . . . 0080 PARA STACK 'STACK'
Symbols:
N a m e Type Value Attr
BEGIN. . . . . . . . . . . . . F PROC 0000 CODESG Length=0016
PRICE. . . . . . . . . . . . . L WORD 0002 DATASG
QTY. . . . . . . . . . . . . . L WORD 0000 DATASG
SUBMUL . . . . . . . . . . . . L FAR 0000 External
page 60,132
TITLE SUBMUL Подпрограмма для умножения
;-----------------------------------------------
0000 Codesg segment para 'Code'
0000 SUBMUL PROC FAR
ASSUME CS:CODESG
PUBLIC SUBMUL
0000 F7 E3 MUL BX ;AX-стоимость, BX-количество
0002 CB RET ;Произведение в DX:AX
0003 SUBMUL ENDP
0003 CODESG ENDS
END SUBMUL
Segments and groups:
N a m e Size Align Combine Class
CODESG . . . . . . . . . . . . 0003 PARA NONE 'CODE'
Symbols:
N a m e Type Value Attr
SUBMUL . . . . . . . . . . . . F PROC 0000 CODESG Clobal Length=0003
__________________________________________________________________________
LINK
IBM Personal Computer Linker
Version 2.30 (C) Copyright IBM Corp 1981, 1985
Object Modules: B:CALLMUL1+B:SUBMUL1
Run File: [B:CALLMUL1.EXE]:
List File:[NUL.MAP]: CON
Libraries [.LIB]:
Start Stop Length Name Class
00000H 00015H 0016H CODESG CODE <--Примечание: 2 кодовых
00020H 00022H 0003H CODESG CODE <-- сегмента
00030H 00033H 0004H DATASG DATA
00040H 000BFH 0080H STACKSG STACK
Program entry point at 0000:0000
__________________________________________________________________________
Рис. 21.3. Использование директив EXTRN и PUBLIC.
Программа на рис.21.3 состоит из основной программы CALLMUL1 и
подпрограммы SUBMUL1. В основной программе определены сегменты для стека,
данных и кода. В сегменте данных определены поля QTY и PRICE. В кодовом
сегменте регистр AX загружается значением PRICE, а регистр BX - значением
QTY, после чего происходит вызов подпрограммы. Директива EXTRN в основной
программе определяет SUBMUL как точку входа в подпрограмму.
Подпрограмма содержит директиву PUBLIC (после ASSUME), которая
указывает компоновщику, что точкой входа для выполнения является метка
SUBMUL. Подпрограмма выполняет умножение содержимого регистра AX (цена) на
содержимое регистра BX (количество). Результат умножения вырабатывается в
регистровой паре DX:AX в виде шест.002E 4000.
Так как подпрограмма не определяет каких-либо данных, то ей не
требуется сегмент данных. Если бы подпрограмма имела сегмент данных, то
только она одна использовала бы свои данные.
Также в подпрограмме не определен стековый сегмент, так как она
использует те же стековые адреса, что и основная программа. Таким образом,
стек определенный в основной программе является доступным и в
подпрограмме. Для компоновщика необходимо обнаружить по крайней мере один
стек и определение стека в основной программе является достаточным.
Рассмотрим теперь таблицы идентификаторов, вырабатываемые после
каждого ассемблирования. Обратите внимание, что SUBMUL в таблице
идентификаторов для основной программы имеет атрибуты FAR и External
(внешний), а для подпрограммы - F (для FAR) и Global (глобальный). Этот
последний атрибут указывает, что данное имя доступно из вне подпрограммы,
т.е. глобально.
Карта компановки (в конце листинга) отражает организацию программы в
памяти. Заметьте, что здесь имеются два кодовых сегмента (для каждого
ассемблирования) с разными стартовыми адресами. Последовательность
расположения кодовых сегментов соответствует последовательности указанных
для компановки объектных модулей (обычно основная программа указывается
первой). Таким образом, относительный адрес начала основной программы -
шест.00000, а подпрограммы - шест.00020.
При трассировке выполнения программы можно обнаружить, что команда
CALL SUBMUL имеет объектный код
9A 0000 D413
Машинный код для межсегментного CALL - шест.9A. Эта команда сохраняет в
стеке регистр IP и загружает в него значение 0000, сохраняет в стеке
значение шест.13D2 из регистра CS и загружает в него шест.D413. Следующая
выполняемая команда находится по адресу в регистровой паре CS:IP т.е.