- •Введение
- •Микропроцессор intel 8086
- •Общие принципы работы мп 8086 при выполнении прикладных программ
- •Регистры процессора
- •Способы адресации мпIntel 8086
- •Указание размера операнда
- •Структура программы на языке ассемблера
- •Основные понятия языка ассемблера
- •Написание сегмента данных
- •Написание сегмента стека
- •Написание сегмента кода
- •Написание головной подпрограммы
- •Подготовка программ к выполнению
- •Отладка программ в Turbo Debugger
- •Лабораторный практикум
Написание сегмента стека
Сегмент стека обычно состоит из директивы DB 256 DUP (?),предписывающей ассемблеру выделить 256 байт под стек.
Пример:
Sseg SEGMENT STACK ‘stack’
DB 256 DUP (?)
Sseg ENDS
Написание сегмента кода
Сегмент кода содержит все операторы программы, разби-тые на подпрограммы. В начале этого сегмента указывается директива ASSUME, имеющая такой вид:
ASSUME CS:метка сегм. кода, DS:метка сегм. данных, SS:метка сегм. стека
Подпрограммы определяются с помощью директив PROCиENDPследующим образом:
Имя PROCТип
Операторы
…
RET; Возврат из подпрограммы в точку вызова
Имя ENDP
Имя подпрограммы – это метка, указывающая смещение под-программы в сегменте кода. Тип может быть NEARиFAR. Подпрограммы типаNEARвызываются в пределах текущего сегмента, аFAR– из текущего или другого сегмента.
Как правило, в программах, не использующих библиотеки подпрограмм и имеющих один сегмент кода, все подпрограммы, кроме одной, делают NEAR. Подпрограмма, называемая главной (аналогmainв языкеCили фрагмента кодаbegin…end. в языкеPascal), всегда объявляется какFAR, так как в конце программы необходимо передать управление операционной системе с помощью команды, находящейся в другом сегменте.
Любая подпрограмма может вызывать другие подпрограммы (аналогично тому, как это делается в языках высокого уровня). Вызов подпрограммы осуществляется с помощью команды CALL:
CALLимя_подпрограммы
При вызове подпрограмм типа NEARв стек записывается смещение следующей заCALLкоманды и производится переход к подпрограмме. По командеRETэто значение из стека записывается в регистрIP, и программа продолжается со следующей заCALLкомандой. Для подпрограмм типаFARв стек записывается как смещение, так и сегмент точки возврата. По командеRETвCS:IPзаписывается адрес точки возврата.
Пример
сегмента кода:
Cseg SEGMENT ‘code’
ASSUME cs:Cseg, ds:Dseg, ss:Sseg
Sub PROC NEAR
…
RET
Sub ENDP
Main PROC FAR
…
CALL Sub
…
RET
Main ENDP
CsegENDS
Написание головной подпрограммы
Главная подпрограмма вызывается системой, однако в стек адрес возврата не записывается. Чтобы вернуться в операционную систему, нужно выполнить команду, находящуюся в самом начале так называемого программного префикса. Программным префиксом (PSP) называется область памяти размером 256 байт, используемая для хранения переменных окружения, командной строки, некоторых других данных и предшествующая в памяти сегменту кода:
PSP Сегмент кода
Номер сегмента PSPсистема записывает в регистрDS. Смещение первой его команды всегда равно нулю.
В начале работы главной подпрограммы необходимо записать в стек адрес первой команды PSP: сначалаDS, а затем ноль. Тогда командаRETв конце головной подпрограммы извлечет этот адрес из стека и следующей выполнится команда возврата в операционную систему.
Поскольку при старте программы в DSнаходится номер сегментаPSP, вDSнеобходимо явно записать номер сегмента данных. Это делают так:
MOV AX, Dseg
MOV DS, AX
Поэтому головную процедуру пишут обычно так:
Main PROC FAR
PUSHDS; ЗанесениеDSв стек
MOVAX, 0 ; ОбнулениеAX
PUSHAX; Занесение нуля в стек
MOVAX,Dseg; НастройкаDSна сегмент данных
MOV DS, AX
…
RET
MainENDP
Пример программы на ассемблере
Приведем пример программы, вычисляющей сумму трех чисел: X,Y,Zи записывающей результат в переменнуюRES.
; Сегменты не более 64 килобайт
.MODEL SMALL
; Сегмент стека
Sseg SEGMENT STACK ‘stack’
DB 256 DUP (?)
Sseg ENDS
; Сегмент данных
Dseg SEGMENT ‘data’
X DB 3
Y DB 5
Z DB 7
RES DB ?
Dseg ENDS
; Сегмент кода
Cseg SEGMENT ‘code’
ASSUME CS:Cseg,
DS:Dseg, SS:Sseg
; Процедура добавленияZк суммеXиYвALи записи результата вRES
Sumres PROC NEAR
ADD AL, Z
MOV RES, AL
RET
SumresENDP
; Головная подпрограмма
MainPROCFAR
; Подготовимся к возврату в операционную систему
PUSH DS
MOV AX, 0
PUSHAX
; Настроим DSна наш сегмент данных
MOV AX, Dseg
MOV DS, AX
; Делаем вычисления
MOVAL,X
ADD AL, Y
CALL Sumres
; Передача управления первому оператору вPSP
RET
Main ENDP
Cseg ENDS
ENDMain
