Программа на языке ассемблера

Структура программы

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

Предложения ассемблера бывают четырех типов:

1) команды или инструкции, представляющие собой символические аналоги машинных команд. В процессе трансляции инструкции ассемблера преобразуются в соответствующие команды системы команд микропроцессора;

2) макрокоманды - оформляемые определенным образом предложения текста программы, замещаемые во время трансляции другими предложениями;

3) директивы, являющиеся указанием транслятору ассемблера на выполнение некоторых действий. У директив нет аналогов в машинном представлении;

4) строки комментариев, содержащие любые символы, в том числе и буквы русского алфавита. Комментарии игнорируются транслятором. Комментарий начинается с символа “;” и действует в пределах текущей строки.

Примеры программ

1) Программа сложения двух чисел:

s_s segment stack "stack" ;адрес начала сегмента стека

dw 12 dup(?) ;зарезервировано в памяти 24 ячейки с любым

;значением

s_s ends ;адрес конца сегмента стека

d_s segment ;адрес начала сегмента данных

aa dw 7145h, 23h ;данные, т.е. числа 7145h и 23h записаны по

;адресу аа и аа+2 соответственно, т.к. они

;определены как слова

sum dw 0 ; данное, т.е. число 0 записано по адресу sum

d_s ends ;адрес конца сегмента данных

c_s segment ;начало сегмента кода

assume ss:s_s,ds:d_s,cs:c_s ;псевдооператор, определяющий,

;каким сегментным регистрам

;соответствуют назначенные

;метками адреса начала сегментов

begin: ;начало пpогpаммы

mov ax,d_s ;пересылка в регистр сегмента данных (ds) адреса

;начала сегмента данных, т.е. метки начала сегмента

;данных

mov ds,ax ;пересылку в ds можно сделать только через

;промежуточную пересылку в рабочий регистр,

; например ax, т.к. из памяти в сегментные регистры

; записывать нельзя

mov ax,aa ;пересылка в регистр ax содержимого, находящегося

;по адресу аа, т.е. числа 7145h

add ax,aa+2 ;сложить число, которое находится в регистре ax с

;содержимым, находящимся по адресу аа+2

;т.е.числа 23h и результат записывается в регистр ax

mov sum,ax ;переслать содержимое ax, т.е. результат в ячейку

;памяти по адресу sum

mov ah,4ch ;для правильного завершения программы

;необходимо переслать в регистр ah - байт 4ch

int 21h ;и вызвать прерывание равное 21h

c_s ends ;конец сегмента кода

end begin ; конец программы. Метки начала и конца

;программы должны совпадать.

2) Программа сложения двух чисел c учетом переноса из старшего разряда:

s_s segment stack "stack" ;начало сегмента стека

dw 12 dup(?) ; зарезервировано в памяти 24 ячейки

s_s ends ;конец сегмента стека

d_s segment ;начало сегмента данных

aa dw 5435h,4531h; данные, т.е. числа 5435h, 4531h записаны

;по адресу аа и аа+2 соответственно, т.к. они

;определены как слова

s1 dw 2h ; по адресу s1 записано число 2

sum dw ? ;любое данное записано по адресу sum (это метка)

d_s ends ;конец сегмента данных

c_s segment ;начало сегмента кода

assume ss:s_s,ds:d_s,cs:c_s;

begin: ;начало программы

mov ax,d_s

mov ds,ax

mov ax,aa ;пересылка в регистр ax содержимого, находящегося

;по адресу аа, т.е. числа 5435h

add ax,aa+2 ;сложить число, которое находится в регистре ax с

;содержимым, находящимся по адресу аа+2, т.е.числа

;4531h, результат записывается в ax

jno kof ;перейти, если нет переполнения (OF=0)

mov ax,aa ;если OF=1 - переполнение, выбрать опять число

add ax,s1 ;и сложить его с другим

kof: mov sum,ax ;переслать содержимое ax, т.е. результат в ячейку

;памяти по адресу sum

mov ah,4ch ;для правильного завершения программы необходимо

;переслать в регистр ah4ch

int 21h ;и вызвать прерывание равное 21h

c_s ends ;конец сегмента кода

end begin ;конец программы

3) Программа сброса 3 и 4 бита в байте:

s_s segment stack "stack"

dw 12 dup(?)

s_s ends

d_s segment

aа db 75h

sum db 0h

d_s ends

c_s segment

assume ss:s_s,ds:d_s,cs:c_s

begin:

mov ax,d_s

mov ds,ax

mov dl,aa ;пересылка в регистр dl содержимого, находящегося

; по адресу аа, т.е. числа 75h

and dl,11100111b ;сбросить биты 3 и 4, т.е. установит в ноль

mov sum,dl ; записать результат в sum

mov ah,4ch

int 21h

c_s ends

End begin

4) программа вывода на экpан стpоки символов:

s_s segment stack "stack"

dw 12 dup(?)

s_s ends

d_s segment

soob dw ‘ОК’,0ah,0dh,’$’ ;в первых апострофах то, что выводим,

;затем 0ah -пеpевод стpоки,

;0dh- возвpат каpетки, $- конец строки

d_s ends

c_s segment

assume ss:s_s,ds:d_s,cs:c_s

begin:

mov ax,d_s

mov ds,ax

mov ah,9h ;вывод стpоки символов на экpан - функция 9h

lea dx,soob ;в dx - адpес стpоки для вывода

int 21h ;выводим стpоку на экран

mov ah,4ch

int 21h

c_s ends

End begin

Примечание. Команда LEA, в отличие от команды MOV записывает в указанный регистр адрес ячейки, где находится данное, а не само данное по этому адресу.

5) пpогpамма, использующая условный переход:

d_s segment

aa dw 10

d_s ends

c_s segment

assume ss:s_s,ds:d_s,cs:c_s

begin:

mov ax,d_s

mov ds,ax;

cmp aa,10

jbe met1 ; вызывает переход к метке met1,

;если содержимое аа меньше или равно 10

;иначе будут выполняться следующие команды

met1: mov ah,4ch

int 21h

c_s ends

End begin

6) пpогpамма, использующая команды ввода-вывода (программа проверки, установлен ли математический сопроцессор)

d_s segment

sum db 0

d_s ends

c_s segment

assume ss:s_s,ds:d_s,cs:c_s

begin:

mov ax,d_s

mov ds,ax

mov al,14h ;переписать N регистра (14-хранит информацию о

out 70h,al ;периферии) в 70h порт (через дополнительную

; пересылку в регистр al)

in al,71h ;прочесть содержимое 14 регистра через 71h порт

test al,10b ;проверить 1-ый бит, который указывает, есть ли

;сопроцессор

jz no_c ;если не установлен 1 бит, то переход на метку

................ ;если установлен (равен 1), то выполняются следующие

.............. ;команды

mov sum, al

no_c: mov sum, ah ;сопроцессора нет

mov ah,4ch

int 21h

c_s ends

End begin

7) пpогpамма, использующая вызов процедуры:

s_s segment stack "stack"

dw 12 dup(?)

s_s ends

d_s segment

aa dw 10

d_s ends

c_s segment

assume ss:s_s,ds:d_s,cs:c_s

begin:

mov ax,d_s

mov ds,ax

call pr1 ;вызов подпрограммы

call pr1 ;вызов подпрограммы

mov ah,4ch

int 21h

pr1 proc near ;начало подпрограммы (ближний вызов)

push ax ; записать в стек регистр ах

mov ax, aa

pop ax ;выбрать из стека регистр ах

ret ;команда возврата на следующую команду после

;вызова процедуры

pr1 endp ;конец подпрограммы

c_s ends

End begin

Программы, имеющие такой вид, компонуются в файл с расширением .EXE. Для инициализации ассемблерной пpогpаммы необходимо: 1) указать ассемблеpу, какие сегментные pегистpы должны соответствовать сегментам; 2) загpузить в DS адpес начала сегмента данных. Пpогpамма в фоpмате ЕХЕ может иметь любой pазмеp. Программа с расширением .COM не должна пpевышать 64 Кбайт памяти.

При определении данных, начинающихся с буквы, необходимо перед буквой ставить цифру 0.

Наши рекомендации