Регистр ЕСХ исполь­зуется в качестве индекса дополнительно, главная его «специализация» использование его в качестве счетчика. Сначала вторая команда программы загружает в него значе­ние, хранящееся в памяти по адресу N. Далее на каждой итерации цикла значение в этом регистре уменьшается на 1. Команда условного перехода JG выполняет пе­реход к началу цикла по адресу STARTADD, если [ЕСХ] > 0. Когда содержимое регистра ЕСХ становится равным нулю, это означает, что все числа списка сложе­ны. В таком случае переход не осуществляется и следующая команда пересылки сохраняет содержимое регистра ЕАХ в памяти по адресу SUM.

Так как счетчик (регистр ECX) меняет свое значение от n до 1, то если бы мы не уменьшили значение базового регистра на 4, то мы сложили бы n чисел, заканчивая NUM2, а начиная NUMn+4 т.е. с адресами на 4 больше, чем NUM1 и NUMn.

Используемая в программе команда LOOP STARTADD объединяет функции двух команд:

DEC ЕСХ

JG STARTADD

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

                               LEA                      EBX,NUM1                                                                                       ;Загрузка адреса NUM1 в базовый регистр

                               SUB                       EBX,4                                                                                                                 ;Уменьшение адреса на 4

MOV                        ECX,N                                                                                                ; Загрузка значения счетчика  

                               MOV                     EAX,0                                                                                                 ;Обнуление регистра суммы

STARTADD:          ADD                      EAX,(EBX+ECX*4)                                        ;Определение адреса следующего и

;прибавление к EAX

LOOP                      STARTADD                                                                                      ;Уменьшение на 1 счетчика ECX и

                                                                                                                                                                               ;если ECX >0, переход на STARTADD

                               MOV                     SUM,EAX                                                                                         ;Пересылка суммы по адресу SUM      

                                               …                           …                                                         

SUM                                                        DEF                       ?                                                                                                                              ;сегмент данных программы

N                                                                              DEF                       n                                                           

NUM1                                      def                       ?                                            

NUM2                                      def                       ?                                                            

NUM3                                      def                       ?                                            

…              …                                                         

NUMn                                                      def                       ?

Рис. 5.8. Программа для процессоров IA-32, выполняющая сложение последовательности чисел;

Обработка списков и массивов всегда требует внимательности, особенно при выборе условия перехода и метода индексации — с нуля или единицы. Неверный выбор может привести к ошибкам в программе. В языках высокого уровня эта за­дача упрощается, поскольку к элементам списка можно явно обращаться как к LIST(0), LIST(1), ..., LIST(n-l), а начало и конец цикла можно явно связать со значениями индекса при помощи таких выражений, как

FOR I FROM 0 UPTO (n-1)

или

FOR I FROM (n-1) DOWNTO 0

Это краткое описание некоторых из числа наиболее часто используемых ко­манд IA-32 и примера программного цикла можно считать введением в систему команд и язык ассемблера IA-32. В следующем разделе рассматривается машин­ное представление команд этого семейства процессоров.

Формат машинных команд

Общий формат машинных команд процессоров IA-32 показан на рис. 5.9. Ко­манды имеют переменную длину — от 1 до 12 байт и могут включать до четырех полей. Команды длиной в 1 байт содержат только обязательное поле кода опера­ции. Как правило, длина этого поля составляет 1 байт, иногда — 2 байта. Информа­ция о режиме адресации содержится в одном или двух байтах, следующих за полем кода операции. В тех командах, где для формирования исполнительного адреса операнда используется только один регистр, поле режима адресации имеет длину 1 байт. Второй байт нужен для кодирования двух последних режимов адресации (см. табл. 5.1). В этих режимах для формирования исполнительного адреса опе­ранда нужно иметь 2 байта.

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

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

Однако для большинства команд и режимов адресации регистры задаются в поле режима адресации.

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


Рис. 5.9. Формат команды IA-32

Однобайтовые команды

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

INC EDI

и

DEC ECX

регистры общего назначения EDI и ECX задаются 3-битовыми кодами в байте кода операции.

Кодировка непосредственной адресации

Режим непосредственной адресации задается в поле кода операции. Например, команда

MOV ЕАХ,820

имеет длину 5 байт. В однобайтовом поле кода операции определяется операция пересылки, указывается, что операнд задан непосредственно и имеет длину 32 раз­ряда, а также задается имя регистра назначения. За кодом операции следует 4-байтовое значение 820. Если непосредственно заданный операнд имеет длину 8 бит, то для команды

MOV DL,5

достаточно 2 байт.

Режимы адресации и поля смещения

Если команда имеет два операнда, то один из них должен содержаться в регистре, а другой — либо в регистре, либо в памяти. Для этого правила имеются два ис­ключения, когда оба операнда могут находиться в памяти. Одно из них касается команд, в которых первый операнд задается в режиме непосредственной адреса­ции, а второй — в режиме прямой адресации. Другое исключение относится к операциям проталкивания и выталкивания значений из стека процессора. Стек располагается в памяти в сегменте стека, и в него можно поместить значение из памяти, а можно вытолкнуть из него значение в память. Эти операции подробно описаны в разделе6.6.

Когда оба операнда находятся в регистрах, для поля режима адресации доста­точно одного байта. Например, команда

ADD EAX,EDX

занимает 2 байта. В первом из них содержится код операции, а во втором — коды двух регистров.

Рассмотрим несколько примеров кодирования команд, один операнд которых располагается в памяти, а другой в регистре. Команда

MOV ECX,N

в программах на рис. 5.4 кодируется 6 байтами: один для кода операции, один для поля адресного режима, в котором задается режим прямой адресации и ре­гистр ЕСХ, и четыре байта для адреса памяти N. Для кодирования команды

ADD EAX,[EBX+EDI*4]

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

MOV DWORD PTR[EBP+ESI*4+DISP],10

Директива ассемблера DWORD PTR указывает, что непосредственно задан­ный операнд 10 имеет длину 32 бита. В других языках ассемблера размер операн­да часто определяется мнемоническим обозначением команды. Например, в язы­ке процессора Motorola 68000 команда MOVEB определяет 1-байтовый операнд, а команда MOVEL — 4-байтовый. Если в ко­манде задано 32-разрядное значение смещения DISP, для ее кодирования требу­ется 11 байт: один байт для поля кода операции, два — для поля режима адреса­ции и по четыре байта для полей смещения и непосредственно заданного операн­да. В табл. 5.1 указано, что смещение может иметь дину 8 или 32 бита. Его размер задается в первом из двух байтов поля режима адресации.

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

MOV EAX,LOCATION

которая загружает в регистр ЕАХ содержимое памяти по адресу LOCATION, и команды

MOV LOCATION,EAX

загружающей в память по адресу LOCATION содержимое регистра ЕАХ, в поле кода операции содержится бит, который называется битом направления. Он ука­зывает, какой из операндов является исходным.

Правила кодирования полей кода операции и адресного режима в архитектуре IA-32 довольно сложны, не всегда унифицированы и имеют множество исключе­ний. И хотя это несколько затрудняет для компилятора использование всех воз­можностей системы команд и режимов адресации, архит IA-32, без сомне­ния, обладает большой гибкостью.


<< назад