Вход/Регистрация
Ассемблер для процессоров Intel Pentium
вернуться

Магда Юрий

Шрифт:

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

 

Следующее 16-разрядное приложение, исходный текст которого показан в листинге 5.1, выводит на экран строки s1 , s2 и s3.

Листинг 5.1. Вывод трех символьных строк на экран

.model small

.stack 100h

.data

s1 DB Odh, Oah, «String 1$»

s2 DB Odh, Oah, «String 2$»

s3 DB Odh, Oah, «String 3$»

sarray label word ; массив, в котором хранятся адреса строк

DW s1 ; s1 иs2

DW s2

DW s3

num DW 0 ; индекс в адресе перехода команды jmp

label_array label word ; массив адресов меток

DW LI ; адрес метки LI

DW L2 ; адрес метки L2

DW L3 ; адрес метки L3

.code

start:

mov AX, @data

mov DS, AX

mov ES, AX

;

mov CX, 3 ; счетчик цикла -> CX

lea DI, label_array ; адрес массива меток

next:

mov s1 , DI

mov BX, num ; индекс перехода -> BX

shl BX, 1 ; умножить на 2 для правильной адресации

; меток в массиве label_array

add SI, BX ; сформировать адрес перехода

; для команды jmp

jmp word ptr [SI] ; перейти по адресу, находящемуся

; в регистре s1 (L1 или L2)

wedge:

inc num ; инкремент индекса переходов

loop next ; повторить цикл

;

L1: ; фрагмент кода при переходе на метку L1

lea DX, s1

mov АН, 9h

int 21h

jmp wedge ; вернуться в цикл

L2: ; фрагмент кода при переходе на метку L2

lea DX, s2

mov АН, 9h

int 21h

jmp wedge

L3: ; фрагмент кода при переходе на метку L3

lea DX, s3

mov AH, 9h

int 21h

;

mov AH, 1h ; ожидать ввода любого символа

int 21h

;

mov AX, 4c00h ; завершение программь

int 21h

end start

end

В этой программе продемонстрирована техника использования команды безусловного перехода jmp для организации трех ветвлений по адресам, определяемым метками LI, L2 и L3. Адрес перехода команды jmp формируется в регистре s1 следующим образом: вначале в s1 загружается базовый адрес массива меток label array, после чего к нему прибавляется смещение, кратное двум (метки LI – L3 имеют двухбайтовый адрес). Затем из сформированного таким образом адреса извлекается смещение одной из меток и выполняется переход на соответствующую ветвь программы. Например, для получения смещения метки L2 необходимо к адресу labelarray прибавить значение 2 (индекс num = 1). После выполнения программы на экране должны отобразиться строки:

String 1

String 2

String 3

Как видно из примера, команду безусловного перехода jmp можно применить для организации ветвлений в программе в зависимости от значения каких-либо параметров. Рассмотрим еще один, довольно сложный пример, в котором команда jmp используется для организации ветвлений и фактически моделируется логическая структура высокого уровня switch ... case языка C++ (или оператор case языка Pascal), обладающая очень большими вычислительными возможностями. В языке ассемблера довольно сложно реализовать такую структуру, и один из вариантов реализации, который мы рассмотрим, базируется на использовании команды jmp.

Пример представляет собой 32-разрядную процедуру (она называется easel). В качестве входного параметра процедура принимает целое число из диапазона 0-2, а в регистре ЕАХ возвращает адрес строки, соответствующий значению параметра. Принципы организации процедур мы рассмотрим в следующих главах, сейчас же акцентируем наше внимание на работе программного кода процедуры easel, не вникая в детали ее взаимодействия с другими частями программы.

Для извлечения единственного параметра используется регистр EBP, a сам параметр для выполнения дальнейших манипуляций помещается в регистр ЕВХ. Исходный текст процедуры представлен в листинге 5.2.


Листинг 5.2. Ассемблерный аналог конструкции case

.686

.model flat

option casemap: none

.data

s1 DB «String 1», 0

s2 DB «String 2», 0

s3 DB «String 3», 0

err DB «Incorrect parameter!», 0

label_array label dword ; массив меток, в котором будут

; находиться смещения

; меток LI, L2 и L3

DD 3 DUP (?)

.code

_case_l proc

push EBP mov EBP, ESP

mov EBX, dword ptr [EBP+8] ; извлекаем параметр (номер строки)

  • Читать дальше
  • 1
  • ...
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: