Команды микропроцессора Intel x86 — КиберПедия 

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Команды микропроцессора Intel x86

2020-11-19 211
Команды микропроцессора Intel x86 0.00 из 5.00 0 оценок
Заказать работу

Команды микропроцессора Intel x86

FASM для Linux

 


Оглавление

1. Архитектура микропроцессора Intel x86. 3

1.2. Индексные регистры.. 4

1.3. Сегментные регистры.. 4

1.4. Регистр флагов. 5

2. Программа формат ELF. 6

3. Задание кодов данных. 7

4. Системный сервис. 9

5. Компилирование программ.. 12

5.1. Загрузка системы.. 12

5.2. Запуск среды разработки. 19

5.4. Создание исполняемого кода. 23

5.5. Завершение работы.. 26

6. Система машинных команд МП x86. 26

6.1. Команды пересылки данных. 26

6.2. Занесение кодов в стек. 28

6.3. Команда обмена значений в регистрах. 29

6.4. Команды передачи управления. 29

6.5. Условная передача управления. 30

6.6. Сканирование строк. 33

6.7. Команды для выполнения действий над байтами. 37

7. Задания для самостоятельной работы.. 39

 

 

Архитектура микропроцессора Intel x86

 В системном программировании под архитектурой микропроцессора (МП) понимают перечень регистров процессора, их разрядность и способ адресации оперативной памяти.

Регистр – внутренняя память процессора. Будем рассматривать 32 разрядную архитектуру процессора. Соответственно разрядность каждого регистра процессора будет равна 32 битам. Регистр процессора используется для временного хранения кодов программы в процессе ее выполнения процессором. Далее рассмотрим классификацию регистров процессора.

Регистры общего назначения

Регистры состоят из двух частей старшей и младшей. Применяются эти регистры для временного хранения данных и адресов. К этим регистрам относятся EAX, EBX, ECX, EDX. Буква E означает enhanced – расширенный регистр. Дело в том 32 разрядная архитектура MП Intel является дальнейшим развитием серии шестнадцати разрядных процессоров Intel. Чтобы сохранить преемственность при разработке программного обеспечения наименования шестнадцати разрядных регистров были дополнены ключевой буквой E.

На рисунке 1.1 показана структура регистра общего назначения.

Рис. 1.1. Регистр общего назначения

Регистр общего назначения состоит из двух шестнадцати битных частей. Младшие шестнадцать битов имеют условное обозначение RX. Где R буква регистра. Кроме того младшая часть делится на две части по восемь бит каждая часть. Эти части условно обозначаются RH и RL.

C учетом выше сказанного регистра EAX будет состоять из следующих частей:

AX – двухбайтовая младшая часть.

AH, AL - однобайтовые части.

Эти условные обозначения можно использовать в командах МП для обращения к соответствующим частям регистра процессора. Аналогично устроены регистры EBX, ECX, EDX.

Индексные регистры

К этим регистрам относятся ESI, EDI, ESP, EBP.

Они хранят индексы – смещения относительно некоторой базы при адресации данных в оперативной памяти.

Регистр EBP – служит для указателя базы в стековых структурах, а регистр ESP – указатель вершины стека.

Кроме того для адресации очередной команды для выполнения МП использует регистр EIP. Этот регистр недоступен для изменения с помощью программного кода.

В отличие от регистров общего назначения эти регистры не делятся на составные части.

Сегментные регистры

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

CS, DS, ES, SS.

Назначение регистров:

· CS – сегмент команд программы.

· DS – сегмент данных.

· ES – сегмент дополнительных данных.

· SS – сегмент стека.

При написании программ для 32 двух разрядной архитектуры эти регистры не используют в программном коде.

Регистр флагов

Это регистр условно называется FLAGS – регистр состояния процессора. Регистр содержит именованные биты, которые используются для анализа состояния МП. В таблице 1.1 приводится описание наиболее важных битов с точки зрения системного программирования флагов.

Таблица 1.1

Биты регистра флагов

Назначение Флаг
Перенос или заем при выполнении арифметических операций CF(Carry Flag)
Устанавливается в 1 если младшие биты результата операции содержат четное число двоичных ед. PF(Parity Flag)
Флаг вспомогательного переноса используется при операциях над упакованным двоично -  десятичными числами. AF(Auxiliary Flag)
Флаг нуля. Устанавливается в 1 если в результате выполнения команды появился результата 0 ZF(Zero Flag)
Флаг знака. Равен 1. Если в результате выполнения команды появилось отрицательное число. SF(Sign Flag)
Флаг переполнения. Выход результата команды за пределы диапазона разрядности регистра процессора OF(Overflow Flag)
Флаг направления. Используется при обработке строк DF(Direction Flag)

Программа формат ELF

При написании программы на языке ассемблера для операционной системы Linux ее текст должен быть написан в соответствии с форматом ELF (Executable and Linkable Format). Создавая такую программу с помощью компилятора FASM (Flat Assembler) программист должен учитывать следующие правила:

· Задать директиву format компилятору для указания типа создаваемого программного кода.

· Указать «точку» входа entry. Точка входа это метка – адрес первой исполняемой команды процессором. С этой команды начинается выполнение команд программы.

· Задать сегмент (segment) команд программы.

· Задать сегмент (segment) кодов – данных программы.

C учетом этих правил структура ассемблерной программы примет вид:

format ELF executable 3

entry start

 

segment readable executable

start:

;Исполняемые команды программы

 

segment readable writeable

;Код данных

Для указания формата ELF программы используется директива format с ключевыми словами ELF executable. Цифра 3 – код операционной системы Linux

При задании сегмента нужно указать, как будет использованы его коды процессором. Для сегмента кодов команд указывают ключевые слова – атрибуты: readable (содержание сегмента можно считывать), executable (коды сегмента – коды команд процессора).

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

В приведенном шаблоне программы точка входа называется start. Это название выбирает программист.

Задание кодов данных

Задание данных программы - кодов происходит в соответствующем сегменте. При этом используются описатели данных:

имя_кода описатель код

Здесь имя_кода – адрес кода в сегменте. Задаются адреса латинскими буквами. Регистр символов не различается. Описатель задает разрядность кода данных (см. таблицу 3.1).

Таблица 3.1.

Описатели кодов данных

Данное Описатель Разрядность
Байт db Байт (восемь бит)
Слово dw Два байта - слово
Двойное слово dd Четыре байта – двойное слово

Значения кодов могут задаваться в десятичной системе исчисления, в двоичной системе, шестнадцатеричной, восьмеричной системе.

Шестнадцатеричный код (code) вводится по одной из схем:

Codeh

Xcode

$code

В конце двоичного кода записывается буква b. Восьмеричный код должен заканчиваться буквой o и начинаться с 0.

Примеры:

code db 0CDh

code1 db 0xFF

code2 db 012o

offset dw 0A10Fh

addr dd 1278FF1Dh

mask db 00001000b

c db?;неопределенное значение.

При задании шестнадцатеричного кода, если он начинается с буквы, то перед буквой нужно задать 0.

Допускается задавать строки и отдельные символы с помощью описателя db в этом случае строка или символ заключаются в пару апострофов ‘. Строка может содержать также коды символов.

Примеры:

mes1 db ‘OK!’     ;строка

mes2 db ‘INPUT:’,10  ;строка с кодами

sym db ‘A’        ;символ

Допускается задание констант в виде K=10. Для определения в процессе компиляции количества байтов в строке используется счетчик текущего адреса $.

Например:

mes db ‘Пример строки символов’

n=$-mes

Чтобы задать буфер для хранения кодов используется директива dup:

Системный сервис

Обращение к сервису – обращение к ядру операционной системы Linux для выполнения определенного действия.  К таким действиям относятся организация ввода-вывода в среде ОС и завершение работы программы.

Для реализации программой любого системного действия она должна вызвать соответствующую функцию ядра ОС. В операционной системе Linux функции ядра обладают определенным номером и именем. При этом говорят, что для выполнения действия в ОС программа выполняет именованный системный вызов.

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

· В регистр EAX заносится номер функции.

· Если функция для своей работы требует задания определенных кодов, то они последовательно заносятся в регистры EBX, ECX, EDX, ESI, EDI.

· Затем следует вызвать прерывание с номером 80h для выполнения выбранной функции с помощью команды INT.

· Результат работы функции возвращается в регистре EAX. Если регистр хранит отрицательное значение, то функция выполнилась с ошибкой.

Значение находящиеся в пределах от fffff000h до ffffffffh представляет собой код ошибки.

Для вывода сообщения на экран – консоль следует использовать системный вызов write. Номер этого вызова 4.

Обращение:

EAX = 4

EBX = 1

ECX = адрес буфера вывода

EDX = число выводимых байтов

В регистр EBX нужно записать номер (дескриптор) – потока вывода. В операционной системе Linux консоль – экран называется устройством стандартного ввода-вывода. За этим устройством закреплен дескриптор с номером 1. Это поток стандартного вывода.

 Заметим, что для вывода на экран можно использовать дескриптор с номером 2. Это номер устройства «стандартной ошибки». Вывод по этому дескриптору выполняют при выводе диагностических сообщений об ошибке в программе.

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

Для выполнения ввода с консоли используется системный вызов read. Это системный вызов с номером 3.

Формат вызова:

EAX = 3

EBX = 0

ECX = адрес буфера

EDX = число символов

В регистр EBX нужно записать код 0. Это номер дескриптора стандартного потока ввода с консоли. В регистр ECX записывают адрес буфера в сегменте данных, куда будут записаны вводимые байты. В регистр EDX записывают ожидаемое число вводимых байтов.

После вызова функции пользователь должен ввести символы с клавиатуры, завершается ввод нажатием комбинации клавиш CTRL + D. Такая комбинация в ОС Linux вводит в стандартный поток ввода признак конца файла и ввод прекращается. В регистре EAX будет храниться число введенных байтов.

Для завершения работы программы и передаче управления операционной системе нужно выполнить системный вызов exit с номером 1.

Вызов этой функции требует записать в регистры коды:

EAX = 1

EBX = код

Здесь код – код завершения работы программы. Если программа не передает код ОС для последующего его анализа, то это значение принимают равным нолю.

Компилирование программ

Разработку программ для операционной системы Linux рассмо-трим в среде ОС Linux Ubuntu 11.04. Будем рассматривать случай, когда данная ОС запускается на виртуальной машине VMware в среде операционной системы MS Windows.

Загрузка системы

Выполним запуск менеджера виртуальных машин. Для этого воспользуемся ярлыком загрузки плеера виртуальных машин VMware, который показан на рисунке 1.2.

Рис.1.2. Пиктограмма плеера

Если такой пиктограммы на рабочем столе нет, то используя кнопку «Пуск» в операционной системе Windows 7 выберите команду меню «Все программы» и найдите группу VMware, откройте группу и запустите плеер.

Программу можно запустить, используя проводник Windows. Программа расположена в папке:

C:\Program Files\VMware\VM ware Player\vmplayer.exe

Главное окно плеера показано на рисунке 1.3.

Рис.1.3. Окно плеера виртуальных машин

Доступные виртуальные машины перечисляются в левой части окна (см. рисункок 1.3). Как видно из рисунка доступно две виртуальные машины. Одна для загрузки Ubuntu версии 11, а другая для загрузки виртуальной машины Windows XP.

Если в списке виртуальных машин нет нужной ОС, то используя команду «Open Virtual Machine» нужно перейти в папку с образом виртуальной машины и включить ее в список доступных машин.

Выберем виртуальную машину Ubuntu, используя мышь и выполним ее запуск. На рисунке 1.4 показан вид окна плеера виртуальных машин после выбора виртуальной машины Ubuntu.

Рис.1.4. Выбор виртуальной машины

Для запуска виртуальной машины в правой части окна нужно выполнить команду: «Play virtual machine».

Время загрузки виртуальной машины зависит от конфигурации конкретной ЭВМ. После завершения загрузки на экране появится окно входа операционной системы Ubuntu, показанное на рисунке 1.5. По умолчанию в данной виртуальной машине создано два пользователя:

User

Ubuntu.

Первый пользователь снабжен паролем 123456, а второй системный пользователь снабжен паролем 123890.

Рис.1.5. Окно входа

Выполните вход под именем User.

На рисунке 1.6 показано окно системы после входа в нее пользователя (фон рабочего стола может отличаться от показанного на рисунке). Необходимо помнить, что ОС Ubuntu является гостевой, и работает на базе виртуальной машины. Визуально это выражается в том, что гостевой ОС предоставляется Windows окно. Им можно управлять с помощью стандартных пиктограмм Windows . Необходимо иметь в виду, что выбор пиктограммы закрытия приведет к аварийному выключению виртуальной машины.

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

Используя инструмент кнопку , можно «открепить» панель, тогда она убирается и появляется при наведении на область панели курсора мыши. На рисунке 1.7 показана подсказка для перехода от виртуальной машины к компьютеру пользователя системы. Переход выполняется путем нажатия клавиш CTRL+ALT. Обратный переход выполняется нажатием клавиш CTRL+G. Работу с гостевой ОС можно также возобновить, выполнив двойной щелчок левой кнопки мыши в поле окна виртуальной машины.

Окно ОС Ubuntu 11.04 состоит из трех областей (см. рисунок 1.6 сверху вниз):

1. Область меню – панели запуска(верхняя часть окна)

2. Центральная область – Рабочий стол.

3. Нижняя  панель окна.

Рис.1.6. Окно системы после входа

 

Рис.1.7. Панель виртуальной машины

Для организации обмена файлами с виртуальной машиной используют флэш накопители. В нижней части окна виртуальной машины расположены пиктограммы работы с устройствами, они  показаны на рисунке 1.8. Крайняя пиктограмма справа – пиктограмма USB накопителя, находящаяся в активном состоянии. Положение этой пиктограммы может отличаться от показанного на рисунке. При подключении нескольких USB устройств таких пиктограмм так же будет несколько.

Рис.1.8. Пиктограммы работы с устройствами.

После подсоединения к компьютеру флэш накопителя виртуальная машина делает попытка передать его «монтирование» гостевой ОС. В ОС Linux после монтирования флэш накопителя автоматически открывается окно навигатора – проводника по файловой системе накопителя. На рисунке 1.9 показан результат монтирования  накопителя KINGSTON.

Рис. 1.9. Смонтированный накопитель

Если автоматические монтирование и открытие навигатора для накопителя не было выполнено, то нужно выполнить команду «Connect» из контекстного меню для пиктограммы съемного накопителя, показанного на рисунке 1.10

Рис. 1.10. Контекстное меню накопителя

Заметим, что в ОС Linux «монтированные» накопители отсоединяются командой их контекстного меню «Извлечь», либо «Безопасно удалить привод».

Для правильного отсоединения накопителя в виртуальной машине следует выполнить команду ОС «Безопасно удалить привод», а затем из контекстного меню виртуальной машины выполнить команду Disconnect! Ни в коем случае нельзя вынимать из USB порта компьютера накопитель без его правильного отсоединения от виртуальной машины. Если это сделать то на накопителе будут потеряны все файлы или часть файлов, которые были на него записаны при работе в ОС Linux.

Окно навигатора для накопителя следует закрыть или свернуть, используя пиктограммы управления окнами. Эти пиктограммы в Ubuntu 11 расположены в верхнем левом углу (см. рисунок 1.11), обозначение аналогично пиктограммам графических окон MS Windows.

Рис. 1.11. Пиктограммы управления окном

Запуск среды разработки

Процесс создания программ в любой операционной системе сводится к выполнению следующих основных действий:

1. Написанию текста программы.

2. Компилированию программы в исполняемый код.

3. Если в процессе компиляции возникли ошибки, то после их исправления выполняется повторная компиляция.

4. Запуск – тестирование созданной программы.

5. Если программа не выполняет требуемые функции в исходный текст программы вносят изменения и повторяют шаги 2, 3, 4.

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

Для запуска среды разработки следует выполнить команду меню ОС:

Приложения > Программирование > Geany.

Окно программы после ее загрузки показано на рисунке 1.12.

Рис.1.12. Загрузка среды программирования

Ввод текста программы

Создадим программу которая выводит контрольное сообщение:

Hello World и завершает свою работу. Наша программа должна будет выполнить два системных вызова: write – для вывода сообщения и   exit – для завершения работы и передачи управления операционной системе.

В окне «Без имени» следует ввести код программы:

format ELF executable 3

entry start

 

segment readable executable

start:

;Вывод сообщения на консоль

mov eax,4

mov ebx,1

mov ecx,msg;Адрес сообщения

mov edx,msg_size;Число байтов сообщения

int 0x80

;Завершение работы программы

mov eax,1

mov ebx,0

int 0x80

 

segment readable writeable

msg db 'Hello World!',0xA

msg_size = $-msg

После набора текста программы следует его сохранить под именем hello.asm в каталоге – папке fasm. Каталог находится в домашнем каталоге пользователя Use системы.

Что бы выполнить сохранение файла нужно выполнить команду меню системы программирования Файл > Сохранить.

Рис.1.13. Сохранение файла программы

В появившемся окне следует ввести имя файла hello.asm и сделать каталог fasm текущим (см. рисунок 1.13), затем следует нажать командную кнопку «Сохранить». Следует иметь в виду, что в ОС Linux нет понятия расширение файла в отличие от ОС Windows. Файл может иметь окончание, которое отделяется точкой от имени файла. В данном случае окончание файла asm говорит системе разработки, что содержание файла – ассемблерный код. Это приводит к тому, что в редакторе будут выделяться цветом конструкции языка программирования.

Если после сохранения файла синтаксические конструкции не были выделены цветом, то следует проверить установленный синтаксис для написания программного кода. Для этого следует выполнить команду меню программы:

Документ > Установить тип файла > Языки программирования

> Файл Assembler.

Окно системы разработки состоит из трех частей (см. рисунок 1.14):

Рис. 1.14. Окно с введенным текстом программы

Боковой панели. Она расположена слева, используется для визуального отображения структуру создаваемой программы (проекта).

Много оконного редактора. Окно редактирования текущей программы, снабжается ярлыком в верхней его части. На ярлыке выводится имя файла редактируемой программы.

В нижней части выводится окно сообщений.  По умолчанию активна секция «Статус».

Пользователь среды разработки может отключить боковую панель и закрыть окно сообщений, используя соответствующие команды пункта меню «Вид» программы.

Используя мышь можно изменить пропорции окон, для этого следует установить курсор на границу окна и при нажатой левой кнопке изменить пропорции.

Создание исполняемого кода

Перед компиляцией следует убедиться в правильности настроек системы разработки, необходимых для обращения к компилятору FASM!

Нужно выполнить команду меню программы:

Сборка > Установить команды сборки

В открывшемся окне возле секции «Скомпилировать» должна быть записана команда:

./ fasm “% f”

Это команда предписывает вызвать из текущего каталога файла программы компилятор fasm, а параметр % f получит имя файла программы.

В секции «Выполнить» должна быть записана команда:

./% e

После компилирования будет создать исполняемый файл с тем же именем, что и у файла программы без учета окончания. Это имя получить параметр % e. Программа запускается из текущего каталога.

После проверки настроек окно нужно закрыть.

Компиляция программы выполняется с помощью пункта меню «Сборка». Нужно выполнить команду «Скомпилировать». Команда может вызываться с помощью «Горячего ключа» F8.

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

Рис. 1.15. Ошибка компиляции

На рисунке 1.15 показана ошибка при компиляции файла. В строке №7 была неправильно записана команда mov.

После устранения ошибок следует повторить компиляцию.

Если сборка прошла успешно программу следует выполнить с помощью команды меню Сборка > Выполнить. Команда снабжена горячим ключом F5.

Для показа результатов работы программы загружается окно терминала Linux в которое выводится сообщение программы (см. рисунок 1.16) Окно следует закрыть, когда оно больше не нужно.

Рис. 1.16. Вывод сообщения на терминал

При создании программ в ОС Linux, которые осуществляют вывод информации в окно терминала, для разделения выводимых сообщений на строки и перевода курсора на следующую строку используется управляющий код LF (Line Feed). Значение этого кода равно 10 в десятичной системе и 0A в шестнадцатеричной системе. В нашем примере этим кодом завершается сообщение Hello World!

Что бы ускорить процесс разработки программы среда разработки открывает доступ к часто используемым командам с помощью панели инструментов. В таблице 5.1 приведены пиктограммы инструментов используемых при компилировании программы.

Таблица 5.1

Инструменты

Команда Инструмент
1 Создать новый файл
2 Открыть существующий файл
3 Сохранить текущий файл
4 Сохранить все открытые файлы
5 Обновить текущий файл с диска
6 Закрыть текущий файл
7 Шаг назад, шаг вперед при редактировании текста программы
8 Скомпилировать текущий файл
9 Выполнить скомпилированную программу

 

Панель инструментов можно скрыть или показать, используя команду пункта меню «Вид».

Завершение работы

Перед завершением сеанса работы следует закрыть все окна системы разработки программного обеспечения. Затем закрыть программу Geany.

Если к виртуальной машине были присоединены USB накопители или устройства их нужно ПРАВИЛЬНО отключить.

Для безопасного завершения работы OC Ubuntu следует использовать команду меню Система > Выключить.

Можно воспользоваться пиктограммами выключения , расположенными в верхней панели. Вторая такая пиктограмма темного цвета расположена в верхнем правом углу окна операционной системы.

Не закрывайте окно виртуальной машины, как обычное окно MS Windows! Это может привести к повреждению файла виртуальной машины Ubuntu, что сделает невозможным повторную ее загрузку.   

Команды пересылки данных

MOV – запись числа в регистр или ячейку памяти.

MOV R1,R2;R1=R2

MOV R,A;R=A

MOV [R],A;Запись в ячейку памяти значения

MOV R,[R];Сохранения из памяти значения

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

MOVSB – пересылка байтов в оперативной памяти, для работы команды настраиваются регистры процессора:

ESI – адрес источника байтов.

EDI – адрес приемника байтов.

ECX= n – количество пересылаемых байтов.

Для пересылки n байтов команда снабжается префиксом REP. Перед вызовом команды обычно используют команду CLD. Команда сбрасывает флаг регистра флагов направления DF для пересылки байтов в порядке возрастания их адресов в буфере.

Если байты буфера пересылаются в порядке убывания адресов, значение DF = 1. Для установки флага используется команда STD.

Таким образом, при значении DF=0, после завершения пересылки байтов регистры ESI и EDI будут хранить адрес следующей ячейки памяти буфера  источника и буфера приемника.

При DF=1 эти регистры хранят адрес ячейки памяти, которая находится п еред ячейкой буфера источника и приемника.

Упражнение 6.1. В сегменте данных задана строка “ABCDEFG”, которая хранится по адресу msg и буфер buf размером 128 байтов. Каждый байт буфера хранить код LF. Требуется переслать символы строки в буфер.

Тогда команды пересылки байтов строки в буфер примут вид:

mov esi,msg;ESI > msg

mov edi,buf;EDI > buf

mov ecx,msg_size; Число байтов

cld;DF = 0

rep movsb;Переслать все байты

Составьте программу, которая выводит исходную строку до пересылки на экран терминала и содержание буфера, после завершения пересылки кодов.

Занесение кодов в стек

PUSH R – запись числа в стек.

POP R – извлечение числа из стека.

При работе со стеком необходимо иметь в виду, в стек можно записывать значение регистра целиком, либо его младшую часть.

Так правильные команды занесения значения регистра EAX примут вид:

push eax

push ax

Следующие команды недопустимы:

push al

push ah

Команда позволяет записывать в стек значения по адресу из оперативной памяти.

Пример. В сегменте данных заданы два адреса:

addr1 dw 1234h

addr2 dd 890fh

Тогда будут допустимы такие команды

push [addr1]

push [addr2]

Следует помнить, что в операциях со стеком могут использоваться только операнды размером с машинное слово (word) и размером в двойное машинное слово (dword)

Для команды POP справедливы те же правила. Так верными будут команды:

pop ebx

pop bx

Команда:

pop bl

недопустима.

Команды передачи управления

JMP label – безусловный переход.

Данная команда позволяет передать управление команде, которая находиться в том же сегменте, что и команда JMP. В команде label — метка (адрес) команды, которая получает управление.

Пример. Схема передачи управления:

jmp fin

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

…................... 

;Завершение работы программы

 fin:

mov eax,1

mov ebx,0

int 0x80

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

Для выполнения определенного участка программа несколько раз используется команда LOOP.

Формат команды:

LOOP label – циклическое выполнение команд. Первая команда блока команд помечается меткой   label. Количество повторений цикла - итераций заносится в регистр ECX:

Пример. Организация цикла на 70 итераций:

mov ECX,70

go:

;Команды

loop go

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

Общее число возможных итераций цикла равно 232. Допускается использовать не весь регистр для задания счетчика итераций.

Так число итераций можно записать в младшую часть регистра CX или в одну из частей CH или CL. При этом будет меняться число возможных итераций цикла.

CMP R,A

CMP R1,R2

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

Команда выполняет вычитание второго операнда из первого, и при этом изменяются значения флагов CF, ZF, SF и ОF.

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

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

Таблица 6.1

Команды условного перехода

Номер команды Команда Бит Описание
1 JZ ZF=1 Получено нулевое значение
2 JNZ ZF=0 Нет нулевого значения
  JO OF=1 Переполнение в результате выполнения команды вычисления значения
4 JN OF=0 Нет переполнения
5 JS SF=1 Результат выполнения команды отрицательное число
6 JNS SF=0 Число положительное
7 JE ZF=1 Сравниваемые коды равны
8 JNE ZF=0 Коды не равны
9 JA CF=0;ZF=0   Один код большего другого, используется при сравнении без знаковых кодов.
10 JB CF=1 Код меньше. Используется при сравнении без знаковых кодов.
11 JL SF<>OF Код меньше
12 JG ZF=0;SF=OF Код больше
13 JLE ZF=1;SF<>OF Код меньше, либо равен
14 JGE SF=OF Код больше, либо равен
15 JC CF=1 Заем единицы при вычислениях
16 JNC CF=0 Нет заёма при вычислениях

        

Пример. Проверка равенства кода в регистре определенному значению.

cmp AX,90

je ok; Да, равно!

Упражнение 6.2. Дано два машинных слова n1 и n2. Требуется определить, в каком из этих машинных слов записан больший положительный код.

Код проверки машинных слов примет вид:

mov eax, dword [n1];Загрузка кода первого слова

cmp ax, [n2]       ;Загрузка кода второго слова

jb lt   ;Второй код больше

ja gt   ;Первый код больше

jmp eqv;Коды равны

lt:

 ;Сообщение – первый вариант   

 mov ecx,mes_max1;n2 > n1

 jmp fin;Завершить работу

gt:

 ;Сообщение – второй вариант

mov ecx,mes_max2;n1 > n2

jmp fin;Завершить работу

eqv:

  Сообщение о равенстве кодов   

mov ecx,mes_eq;n1 = n2

fin:

;Вывод сообщения и выход в ОС

Создайте сегмент данных в котором определите два слова с кодами и три варианта контрольных сообщений с одинаковыми количеством символов. Откомпилируйте программу. Проверьте разные значения кодов.

Сканирование строк

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

Для сканирования байтов строк можно использовать команды CMPSB и SCASB.

Команда CMPSB

Команда используется для сравнения кодов байтов двух строк. Байты строк сравниваются по парно. Формат команды:

ESI – адрес первой строки.

EDI – адрес второй строки.

ECX= n – количество пересылаемых байтов.

Команда вызывается с повторителями REPE ( повторять пока коды байтов равны), REPNE ( повторять пока коды байтов неравны).

Перед сканированием обычно выполняют командой CLD сброс флага направления DF.

Результат сканирования проверяется командами условного перехода. Если команда выполнялась с повторителем REPE и все сканированные байты хранят одинаковый код, то будут выполнены команда условного перехода JE или JZ (ZF=1).

Если команда выполняется с повторителем REPNE, и будет найдена пара байтов с одинаковым кодом, то выставляется флаг ZF = 1 и можно также использовать команды условного перехода JE или JZ.

Результат сканирования можно проверять с помощью команд JNE, JNZ (ZF = 0).

Сравнение происходит путем вычитания кодов второго операнда строки из первого.

Упражнение 6.3. Требуется написать программу для поиска одинакового  байта у двух строк mes1 = “ABCDEFG” и mes2 = “012D567”. Если строки содержат общий байт, программа выводит контрольное сообщение.

Код сравнения строк примет вид:

mov esi,mes1;Адрес первой строки

mov edi,mes2;Адрес второй строки

mov ecx,n;Число сравниваемых байтов

cld;Флаг направления DF = 0

repne cmpsb;Сравнивать байты пока не равны

je ok;Есть общий байт ZF = 1?

jmp fin;Нет — конец работы

ok:;Да — вывести контрольное сообщение

mov eax,4

mov ebx,1

mov ecx,ok_mes;Контрольное сообщение

mov edx,l_ok;Число байтов сообщения

int 0x80

;Завершение работы прогр


Поделиться с друзьями:

Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой...

Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...

Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.281 с.