Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MAIN_ASS.DOC
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
153.09 Кб
Скачать

Язык ассемблера и программирования Глава 1. Директивы языка ассемблера Директива segment

Формат директивы:

имя_сегмента SEGMENT [выравнивание] [объединение] [класс]

.

.

.

имя_сегмента ENDS

Операнд выравнивания определяет начальную границу сегмента.

PARA (по умолчанию)-сегмент начинается на границе параграфа.

BYTE-сегмент может начинаться в произвольном месте.

WORD-сегмент начинается на границе слова.

Объединение указывает способ обработки сегмента при компоновке.

NONE: Значение по умолчанию. Сегмент должен быть логически отделен от других сегментов. Предполагается, что сегмент имеет собственный базовый адрес.

PUBLIC: Все PUBLIC-сегменты, имеющие одинаковое имя и класс, загружаются компоновщиком в смежные области. Все такие сегменты имеют один общий базовый адрес.

STACK: В любой компонуемой программе должен быть определен по крайней мере один сегмент STACK. Если объявлено более одного стека, то стековый указатель SP устанавливается на начало первого стека.

AT-параграф: Параграф должен быть определен предварительно.

‘Класс’: Операнд ‘класс’ может содержать любое правильное имя, заключенное в одиночные кавычки. Данный операнд используется компоновщиком для обработки сегментов, имеющих одинаковые имена и классы.

Директива group

Назначение этой директивы- собрать однотипные сегменты под одно имя так, чтобы они поместились в один сегмент объемом 64 Кбайт. Формат директивы:

имя GROUP имя сегмента [, ......]

Директива assume

Назначение директивы ASSUME- установить для ассемблера связь между сегментами и сегментными регистрами CS, DS, ES и SS. Формат директивы:

Assume сегментный_регистр : имя [, ...]

;Программа hello1.asm без подпрограмм

;Данные программы

DATA SEGMENT

HELLO DB ‘ Здравствуйте!$’

DATA ENDS

; Код программы

CODE SEGMENT

ASSUME CS:CODE,DS:DATA

START: mov ax,DATA

mov ds,ax

mov ah,9

mov dx,OFFSET HELLO

int 21h

mov ah,4ch ;выход из программы

int 21h

CODE ENDS

END START

Рис.1.1 В этом примере приведен пример оформления программы.

Сегмент STACK не определен, поэтому компилятор выдаст предупреждение. В этом случае SS указывает на сегмент данных, а SP=0ffh.

Директива Proc

Эта директива служит для определения процедур. Формат процедуры:

Proc имя [[модификатор_языка] язык] [тип]

[ARG аргументы] [RETURNS список]

[LOCAL аргументы]

[USES список]

.

.

.

[имя] ENDP

Тип процедуры может быть NEAR или FAR. Процедура, находящая в одном сегменте с вызывающей процедурой, имеет тип NEAR. Если операнд опущен, то ассемблер принимает значение NEAR. Если процедура является внешней по отношению к вызывающему сегменту, то процедура должна быть объявлена как PUBLIC.

PUBLIC имя_процедуры

имя_процедуры PROC FAR

; Программа hello2.asm состоит из вызывающей и вызываемой подпрограммы

AStack SEGMENT STACK

DW 12 DUP(?)

AStack ENDS

AData SEGMENT

Hello DB ‘Здравствуйте!$’

AData ENDS

ACode SEGMENT

ASSUME CS: ACode,DS: AData,SS: AStack

WriteMsg PROC NEAR

mov ah,9

int 21h

ret

WriteMsg ENDP

Main PROC FAR

COMMENT !

Формирование и запись в стек адреса PSP, в первых двух байтах которого хранится код завершения программы int 20h. В этом случае выход в MS-DOS может осуществляться по инструкции ret. При загрузке программы в регистре DS хранится адрес PSP программы.

!

push ds

sub ax,ax

push ax ; адрес начала PSP

mov ax,AData

mov ds,ax

mov dx,OFFSET Hello

call WriteMsg

ret

Main ENDP

ACode ENDS

END Main

Рис. 1.2. Процедура Main вызывает процедуру WriteMsg.

Здесь используется ближний вызов, так как эти две процедуры находятся в одном сегменте. Следует иметь в виду, что программный модуль заканчивается директивой END [имя_точки_входа_в_модуль].

Если проект содержит насколько модулей то имя_точки_входа_в_модуль должно быть определено только в одном главном модуле.

; Программа hello3.asm состоит из вызывающей и вызываемой подпрограммы.

; В WriteMsg используются функции BIOS.

AStack SEGMENT STACK

DW 12 DUP(?)

AStack ENDS

AData SEGMENT

Hello DB ‘Здравствуйте! $’

AData ENDS

ACode SEGMENT

ASSUME CS: ACode,DS: AData,SS: AStack

WriteMsg PROC NEAR

mov bx,dx

mov ah,0eh

mov bh,0

Next: mov al,[bx]

cmp al,’$’

je Quit

int 10h

inc bx

jmp Next

Quit: ret

WriteMsg ENDP

Main PROC FAR

push ds

sub ax,ax

push ax ;адрес начала PSP

mov ax,AData

mov ds,ax

mov dx,OFFSET Hello

call WriteMsg

ret

Main ENDP

ACode ENDS

END Main

Рис. 1.3. Программа, использующая средства BIOS для вывода.

В этой программе для вывода информации используется функция 0Eh прерывания 10h. Формат вызова этой функции:

На входе:

ah = 0eh- запись символа в телетайптном режиме;

al = ASCII - код записываемого символа;

bh = номер страницы видеопамяти (только в текстовых режимах);

bl = цвет символа (в графических режимах).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]