Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Уроки ассемблеру. Быстро и просто. Урок 5


Всем добрый день. Давайте подведём итоги, что мы узнали за прошедшие уроки. А мы узнали вот что:

— Как установить прикладное программное обеспечение;
— Как воспользоваться файлом помощи;
— Как пользоваться отладчиком;
— Как составить и скомпилировать программу на языке ассемблера.

Также, мы узнали немного о десятичной и шестнадцатеричной системах счисления и основных регистрах.

Нормально, если что-то непонятно, да ещё и при таком быстром изучении. В дальнейшем мы ещё раз будем останавливаться на непонятных вопросах, да и тексты программ будут снабжены комментариями.

Сегодня мы узнаем о циклах, операторе безусловного перехода и вызове подпрограмм. Соответственно это операторы loop, jmp и call. Сейчас мы рассмотрим их применение.

loop — оператор, позволяющий организовать цикл. Он использует значение регистра cx, о котором мы писали в 4-м уроке, что он является счётчиком. Допустим, нам надо 5 раз вывести строку "Hello, world". Как это будет выглядеть?

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.
mov cx,5 ;Устанавливаем значение счётчика в 5.

metka:
mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset helloworld ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.
loop metka ;Переходим на метку metka и уменьшаем cx на 1.

int 20h ;Выходим в DOS.

helloworld db 'Hello, world!$' ;Определяем переменную helloworld, доступную побайтно, с фразой
;"Hello, world!". В одинарных кавычках, после знака "!" ставим
;знак "$".

;Завершение программы.
CSEG ends
end begin


Сохраняем в файле test.asm в кодировке 866, а далее ml test.asm /AT
Запускаем файл test.com (через тот же Far, естественно). Мы видим фразу "Hello, world", написанную 5 раз. Если не успеваем её увидеть, нажимаем Ctrl+O (скрыть панели).

Запустим отладчик: afdpro test.com. Используя клавишу F2, посмотрите, как меняется содержимое регистров в верхнем левом углу (для перехода к началу нажимайте F3). Для выхода из отладчика введите в командной строке: quit.

Следующий оператор — jmp. Это оператор безусловного перехода, кто изучал "Бейсик", знает похожий оператор GOTO. Он также использует метки для своего "прыжка". Рассмотрим следующую программу.

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.

jmp exit ;"Прыгаем" на метку exit, не выполняя операторы ниже.
mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset helloworld ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.

exit: ;Метка на шаге 2.
int 20h ;Выходим в DOS.

helloworld db 'Hello, world!$' ;Определяем переменную helloworld, доступную побайтно, с фразой
;"Hello, world!". В одинарных кавычках, после знака "!" ставим
;знак "$".

;Завершение программы.
CSEG ends
end begin

Сохраняем в файле test.asm в кодировке 866, а далее ml test.asm /AT
Запускаем файл test.com. Программа успешно завершает свою работу, но ничего не выводит на экран. Думаю, с этим понятно.

call — оператор вызова подпрограммы. Сама подпрограмма оформляется так:

Начало — NameProg proc, где NameProg — метка начала подпрограммы, proc — оператор;
Конец — ret и в следующей строчке NameProg endp
Почему оператора два, рассмотрим чуть позже. Для усвоения примера возьмём прошлую программу, где ничего не выводится, и несколько её модернизируем.

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.

jmp exit ;"Прыгаем" на метку exit, не выполняя операторы ниже.

NameProg proc ;Начало нашей подпрограммы.
mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset helloworld ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.
ret
NameProg endp ;Конец подпрограммы.

exit: ;Метка на шаге 2.

call NameProg ;Вызываем подпрограмму вывода, которая выводит фразу.

int 20h ;Выходим в DOS.

helloworld db 'Hello, world!$' ;Определяем переменную helloworld, доступную побайтно, с фразой
;"Hello, world!". В одинарных кавычках, после знака "!" ставим
;знак "$".

;Завершение программы.
CSEG ends
end begin

Что же получилось? Командой jmp exit мы "прыгаем" в конец программы. Сразу после этого мы вызываем (call) подпрограмму и выходим. Сама подпрограмма у нас находится выше под командой jmp. Таким образом, теперь мы можем размещать подпрограммы в разных местах.
Для чего это нужно? Для сокращения текста программы, когда приходится много раз применять одинаковые "куски" программ (например, для вывода различных текстов). В последующих примерах мы закрепим это. Не забудьте посмотреть нашу программу через отладчик (afdpro test.com)!

В избранное