Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Инструкции с фиксированной точкой



РРС не имеет вычислительных инструкций для изменения хранимых данных. Вся работа должна выполняться в одном из 32 регистров общего назначения (general-purpose regis­ters, GPRs). Инструкции доступа к хранимым данным могут получать байты, полуслова, слова и двойные слова в обратном порядке байтов (Big Endian). При использовании рас­ширенных мнемоник дополнительно доступны множество инструкций загрузки, сохра­нения, арифметические и с фиксированной точкой, а также специальные инструкции для перемещения из системных регистров или в них.

Инструкции с плавающей точкой

Инструкции с плавающей точкой можно разделить на две категории: вычислительные, включающие арифметические, трассировочные, преобразующие сравнительные; и не­вычислительные, включающие перемещение из хранящих или других регистров или в них. Доступно 32 регистра с плавающей точкой общего назначения; каждый может со­держать данные в формате с плавающей точкой удвоенной точности.


Ассемблер



Обратный порядок байтов/прямой порядок байтов (Big Endian/Litle Endian)

В процессорной архитектуре порядок байтов (Endianness) означает порядок следования бай­тов и операций. PowerPC работает с обратным порядком байтов, это значит, что самый старший байт имеет меньший адрес, а оставшиеся 3 байта следуют за ним (для 32-битового слова). Прямой порядок байтов принят в х86-архитектуре и означает противоположный поря­док. Младший значащий байт имеет наименьший адрес, а оставшиеся 3 байта следуют за ним. Давайте рассмотрим это на примере представления числа 0x12345678 (рис. 2.5).

Обратный 32 битный порядок следования байтов (РРС)

 

0 7 8 1516 23 24 31

Прямой 32 битный порядок следования байтов (х86)

 

0 7 8 15 16 23 24 31

Рис. 2.5. Прямой и обратный порядок следования байтов

Споры о том, какая система лучше, выходят за рамки данной книги, тем не менее вам важно помнить, на какой системе вы пишете и отлаживаете свой код. Для примера ошибки, связанной с последовательностью байтов, можно привести драйвер РО-устройства, исполь­зуемый на архитектуре с другой последовательностью байтов.

Термины Big Endian и Little Endian (тупоконечный и остроконечный) були придуманы Джонатаном Свифтом в Путешествии Гулливера. В этой истории Гулливер знакомился с дву­мя нациями, воевавшими из-за разногласия по поводу того, с какой стороны есть яйцо -с острой или с тупой.

Х86

Архитектура х86 является архитектурой с полным набором вычислительных инструкций Complex Instruction Set Computing (CISC). Инструкции имеют различную длину в зависи­мости от назначения. В классе процессоров х86 Pentium существует три типа регистров: общего назначения, сегмента и статуса/управления. Далее описывается их базовый набор. Вот 8 регистров общего назначения и соглашение по их использованию:

ЕАХ. Аккумулятор общего назначения.

ЕВХ • Указатель на данные.

ЕСХ. Счетчик цикловых операций.

EDX. Указатель ввода-вывода.

ESI. Указатель на данные в сегменте DS.



Глава 2 • Исследовательский инструментарий


EDI. Указатель на данные в сегменте ES.

ESP. Указатель на стек.

ЕВР. Указатель на данные в стеке.

Шесть сегментных регистров используются в реальном (real) режиме адресации, когда память адресуется блоками. При этом каждый байт в памяти доступен по отступу из данного сегмента [например, ES: EDI указывает на память в ES (дополнительном сег­менте) с отступом к значению в EDI]:

• CS. Сегмент кода.

SS. Сегмент стека.

ES# DS# FS, GS. Сегмент данных.

Регистр FLAGS показывает состояние процессора после каждой инструкции. Он мо­жет хранить такие результаты, как нуль (zero), переполнение (overflow) или перенос (carry). EIP - это регистр зарезервированного указателя, обозначающий отступ к текущей инструкции процессора. Обычно он используется с регистром сегмента кода для формирования полного адреса (например, CS: EIP):

EFLAGS. Статус, управление и системные флаги.

EIP. Указатель на инструкции, содержащие отступ от CS.

В архитектуре х86 используется прямой порядок следования данных. Доступ к памя­ти осуществляется порциями по байту (8 бит), слову (16 бит), двойному слову (32 бита) или учетверенному слову (64 бита). Преобразование адресов (и связанных регистров) опи­сывается в гл. 4, но для этого раздела достаточно знать, что в архитектуре х86 код и дан­ные делятся на три категории: управляющие, арифметические и данные.

2.2.2.1 Управляющие инструкции

Управляющие инструкции похожи на управляющие инструкции в РРС, позволяющие из­менять поток выполнения программы. Архитектура х86 использует различные инструк­ции перехода («jump») и метки на выполняемый код, основанные на значениях регистра EFLAGS. В табл. 2.3 перечислены наиболее часто используемые из них. Коды состояния condition codes устанавливаются в соответствии с исходом определенных инструкций. Например, когда инструкция стр (сравнение) обрабатывает два целых операнда, он мо­дифицирует следующие флаги в регистре EFLAGS: OF (переполнение), SF (знаковый флаг), ZF (флаг нуля), PF (флаг четности) и CF (флаг переноса). Таким при вычислении значения инструкции стр устанавливается нулевой флаг.


Ассемблер



Таблица 2.3. Наиболее распространенные инструкции перехода

 

Инструкция Функция Коды состояния EFLAGS
je Переход, если равно ZF=1
jg Переход, если больше ZF=0 и SF=OF
jge Переход, если больше или равно SF=OF
jl Переход, если меньше SF! =OF
jle Переход, если меньше или равно ZF=1
jmp Безусловный переход Безусловный

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

100 pop eax

101 1оор2

102 pop ebx

103 cmp eax, ebx

104 jge loop2

Строка 100

Получение значения из верха стека и помещение его в еах.

Строка 101

Это метка с именем 1оор2.

Строка 102

Получение значения из верха стека и помещение его в ebx.

Строка 103

Сравнение значений еах и ebx.

Строка 104

Переход, если еах больше или равно ebx.

Еще одним способом передачи программного управления являются инструкции call и ret. Обратимся к следующей строке ассемблерного кода:

call my_routine



Глава 2 • Исследовательский инструментарий


Инструкция call передает программное управление на метку my_routine, передавая адрес инструкции, следующей в стеке сразу за инструкцией call. Инструкция ret (исполняемая из my_routine) извлекает возвращаемый адрес и осуществляет переход по нему.

2.2.2.2 Арифметические инструкции

Наиболее известны арифметические инструкции add, sub, imul (целочисленное ум­ножение), idiv (целочисленное деление) и логические операторы and, or, not и xor. Х86-инструкции с плавающей точкой и связанные с ними регистры выходят за рамки этой книги. Различные расширения архитектур Intel и AMD, такие, как ММХ, SSE, 3dNow, SIMD и SSE2/3, значительно ускоряют приложения с интенсивными вычисления­ми, такие, как графические и аудио-вычисления.

2.2.2.3 Инструкции для работы с данными

Данные могут перемещаться между регистрами, между регистрами и памятью и из кон­станты в регистр или память, но не из одного места в памяти в другое. Ниже приведено несколько примеров.

100 mov eax, ebx

101 mov еах, WORD PTR[data3]

102 mov BYTE PTR[char1], al

103 mov eax, Oxbeef

104 mov WORD PTR [my_data], Oxbeef

Строка 100

Передача 32 бит данных из ebx в eax.

Строка 101

Передача 32 бит данных из переменной data3 в памяти в еах.

Строка 102

Передача 8 бит данных из переменной charl в памяти в al.

Строка 103

Передача значения константы Oxbeef в еах.

Строка 104

Передача значения константы Oxbeef в переменную в памяти my_data.

Как видно из предыдущего примера, push, pop и их длинные версии lpush, lpop перемещают данные в стек и из него (по указателю SS: ESP). Подобно инструкции mov, операции push и pop могут применяться к регистрам, данным и константам.


Пример языка ассемблера



Пример языка ассемблера

Мы можем написать простую программу, чтобы увидеть архитектурные различия пре­образования одного и того же С-кода в ассемблер. Для этого эксперимента мы использу­ем компилятор дсс, поставляемый с Red Hat 9, и gcc-кросс-компилятор для PowerPC. Мы приведем С-программу и затем для сравнения код для х86 и PowerPC.

Вас может озадачить количество ассемблерного кода, генерируемого из нескольких строк С. Так как мы просто компилируем из С в ассемблер, мы не будем связывать его ни с каким кодом окружения, таким, как С-библиотеки времени исполнения или создание-уничтожение локального стека, поэтому результат будет значительно меньше, чем настоя­щий ELF-исполнимый файл.

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

Вот пример С-кода:

Count.с

Int main()

2 {

3 int i, j=0; 4

 

5 for(i=0; i< 8; i++)

6 j=j+i; 7

 

8 return 0;

9 }

Строка 1

Здесь объявляется функция main.

Строка 3

Здесь инициализируются нулем переменные i и j.

Строка 5

Цикл for: пока значение i находится в интервале от 0 до 7, установить j равным j плюс i.

Строка 8

Метка перехода назад в вызывающую программу.



Глава 2 • Исследовательский инструментарий


Пример х86-ассемблера

Вот код, сгенерированный для х86 с помощью команды gcc -S count. с из команд­ной строки. После ввода кода база стека указывает на ss: ebp. Код выполнен в формате «AT& T», в котором регистры имеют префикс %, а константы - префикс $. Пример ас­семблерных инструкций приведен в этом разделе для того, чтобы подготовить вас к буду­щим примерам программ, но перед этим нам нужно обсудить непрямую адресацию.

Для обозначения позиции в памяти (например, стека) ассемблер использует специ­альный синтаксис для индексированной адресации. Базовый регистр помещается в круг­лые скобки, а индекс ставится перед скобками. Результирующий адрес находится добав­лением индекса к значению регистра. Например, если %ebp присвоено значение 20, эф­фективный адрес -8 (%ebp) будет (-8)+(20)= 12:

count.s

1.file " count.с"

2.version " 01.01"

3 gcc2_compiled.:

4.text

5.align 4

6.globl main

7.type main, @function

8 main:

#Создание локальной области в памяти из 8 байт для for i и j.

9 pushl %ebp

10 movl %esp, %ebp

11 subl $8, %esp

инициализация i (ebp-4) и j (ebp-8) нулем.

12 movl $0, -8(%ebp)

13 movl $0, -4(%ebp)

14.p2align 2

15.L3:

#Проверка для цикла for

16 cmpl $7, -4(%ebp)

17 jle.L6

18 jmp.L4

19.p2align 2

20.L6:

#Это тело цикла for-loop

21 movl -4(%ebp)/ %eax

22 leal -8(%ebp)/ %edx

23 addl %eax, (%edx)

24 leal -4(%ebp), %eax


Пример языка ассемблера



25 incl (%eax)

26 jmp.L3

27.p2align 2

28.L4:

#Конструкция для вызова из функции

29 movl $0, %еах
3 0 leave

31 ret

Строка 9

Установка базового стекового указателя на стек.

Строка 10

Перемещение указателя на стек в базовый указатель.

Строка 11

Получение 8 байт стека mem начиная с ebp.

Строка 12

Помещение 0 в адрес ebp-8 (j ).

Строка 13

Помещение 0 в адрес ebp-4 (i).

Строка 14

Ассемблерная директива, обозначающая выровненную по полуслову инструкцию.

Строка 15

Созданная на ассемблере метка с именем.L3.

Строка 16

Эта инструкция сравнивает значения i с 7.

Строка 17

Переход на метку.L6, если -4 (%ebp) меньше или равно 7.

Строка 18

В противном случае выполняется переход на метку.L4.

Строка 19

Выравнивание.

Строка 20

Метка.L6.



Глава 2 • Исследовательский инструментарий


Строка 21

Перемещение i в еах.

Строка 22

Загрузка адреса j в edx.

Строка 23


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-03-25; Просмотров: 696; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.051 с.)
Главная | Случайная страница | Обратная связь