Тема 9

Видове инструкции и изпълнението им в процесор Pentium


Важно!! Тези лекции не са предвидени за директен copy-paste на контролното. Прочетете ги внимателно и ги научете. Хора с еднакви контролни ще бъдат санкционирани! Да не кажете после че не сте предупредени



страницата се нуждае от дописване/преглеждане


t09xx

Формата и полетата на инструкцията се развиват с течение на времето и в днешни дни формата е много усложнена.

Префикс

Инструкцията може да има префикс(предхождаща част). Възможни са максимално 4 префикса като може и да няма нито един. В един байт отделен за префикса има специфична кодова информация, която е уникална и няма подобна в кода на инструкцията. Префиксът е част от самата инструкция.

префикс REP OS AS SO
възможна стойност 0/1 0/1 0/1 0/1
  • REP – repeat; повтаряне на следващата инструкция, докато съдържанието на брояча не стане 0 (за това се използва регистъра ECX) като при всяко повторение се намалява съдържанието на брояча с единица. Префиксът се поставя пред инструкцията при писането на програма. Например за инструкцията MOVS (move string) има смисъл да се използва само с префикса repeat. Тъй като самата инструкция MOVS взима от регистъра ESI съдържанието като адрес. Там е източникът на низа, а в EDI е адресът, където се поставя резултата. Низът се мести байт по байт. След прехвърляне на 1 байт от единия низ към другия регистрите се увеличават с 1 (минават на следващия адрес). В брояча C предварително се въвежда размера на низа. Чрез комбинация на инструкцията MOVS, която работи с по 1 байт и инструкцията repeat се извършва обработване на повече байтове. Във флаговия регистър (flag) има клетка D(direction) и когато D = 0 регистрите се увеличават с единица. Когато D = 1 се намаляват.
  • OS (operand size). В кода на операцията е името на инструкцията и всяка операция е за определен брой битове на операнда. След OS операндите се разглеждат като 16 битови при очаквани стандартни 32 битови.
  • AS (address size) обръщат се адресите на операндите от 32 битови към 16 битови адреси.
  • SO (segment overwrite) предназначен е за промяна на сегментите ( CS< SS< DS< ES< FS< GS ). Първоначално инструкцията е за фиксирано използване на сегментите и инструкциите се четат от кодовия сегмент ( стандартно инструкциите се четат от кодовия сегмент ). Има си стеков сегмент, а операндите са в дата сегмент, който може да се покрие от ES, FS и GS. SO сменя DS, ES, FS, GS.

Т.е. имаме

CS    code
SS    stack
DS    data
ES    extra
FS    extra
GS    extra

Първите 3 сегмента са непресичащи се. Последните 4 се пресичат физически. Чрез segment overwrite може да се променя само сегмента на данните и той да се замени с FS, ES или GS.

Инструкцията има следния вид и възможни размери на отделните части
t09xx

  • КОП – код на операцията (opcode). Това е уникален код еднозначно различим от префиксите. Процесора има 256 комбинации за префикси и операции, но инструкциите са повече от 256 , затова КОП може да е 1 или 2 байта, като има и някои 6 битови кодове
7 1 0
d w

w - означава дължина на операндите, например ако процесорът очаква 32-битов операнд и в него постъпи инструкция с поле w = 0 , то той се настройва за работа с 16-битов операнд.
d - означава direction – посока по отношение на прехвърлянето на операндите. При 0 те се прехвърлят от регистъра към паметта, при 1 от паметта към регистрите. Кодът на операцията сам по себе си не носи стойността или адреса на операндите, а само каква е операцията и размера им. Техните адреси се определят в следващите полета на инструкцията.

След КОП има полета за определяне адреса на операндите. Ако не присъстват явно, те се подразбират и са в ESI, EDI.

  • Полето mod r/m е с големина 1 байт и има фиксиран формат състоящ се от 3 части mod, reg и r/m както е указано на схемата. Първият операнд във инструкцията задължително е в регистър.
    • полето mod указва режима, тоест къде е втория операнд. Ако mod = 11, , то и двата операнда са в регистрите( като стойност ) и техните адреси се изчисляват по таблица 1, ако то е различно от 11 , то втория операнд е някъде в паметта.
    • полето reg определя номера на регистър в който е първия операнд (спрямо таблица 1)
    • полето r/m в случая mod = 11 определя номер на регистър, в който е втория операнд, а в другите случаи определя по какъв начин този операнд ще се търси в паметта.(таблица 2)
  • полето sib се използва при базова индексация със скалар на втория операнд, като то се разделя на три части scale, index, base, като чрез него адреса се определя спрямо таблица 3.
  • полето disp указва отместване спрямо базовия регистър.
  • в полето immediate се подава непосредствена стойност на операнд, ако тя присъства в инструкцията

В първия случаи на R-R адресация при mod=11 операндите се намират в следните регистри спрямо таблицата (иначе при mod != 11 само първия операнд се извлича спрямо таблицата)

таблица 1
reg r/m няма w има w
16 32 16 32
w = 0 w = 1 w = 0 w = 1
000 000 AX EAX AL AX AL EAX
001 001 CX ECX CL CX CL ECX
010 010 DX EDX DL DX DL EDX
011 011 BX EBX BL BX BL EBX
100 100 SP ESP AH SP AH ESP
101 101 BP EBP CH BP CH EBP
110 110 SI ESI DH SI DH ESI
111 111 DI EDI BH DI BH EDI

Във всички останали случаи първия операнд е в регистрите и неговата стойност се взима по същия начин, но втория операнд е в паметта, и полето mod r/m показва къде точно е адреса му.
Адрес на втория операнд: (в случая, когат r/m != 100)

Таблица 2
r/m != 100 & mod != 11
r/m mod = 00 mod = 01 mod = 10
000 EAX EAX + d8 EAX + d32
001 ECX ECX + d8 ECX + d32
010 EDX EDX + d8 EDX + d32
011 EBX EBX + d8 EBX + d32
100
101 d32 SS[EBP+d8] SS[EBP+d32]
110 ESI ESI + d8 ESI + d32
111 EDI EDI + d8 EDI + d32

d32, ESI, EDI - явни адреси
d8/d32 - displacement

mod disp sib Imed
00 0 0
01 8bit 0 0
10 32bit 1byte
базов регистър + отместване

В втората колона sib=0 и disp=0, с изключение на случая 101, където d32 не е регистър а отместване( според нас d8 e когато няма alignment, а d32 – когато има ). В случая това означава,че имаме явен адрес. Във всички случаи данните са в data segment, освен при 101, когато са в stack segment. Кодът 100 е запазен, ако той присъства то полето sib става един байт( има го ) и адреса се указва чрез базов адрес, индекс и отместване. Тук
s – скаларен множител, който е 1,2,4 или 8 в зависимост от таблицата
i – номер на индексен регистър
b- номер на базов регистър
Адреса се сформира по следния начин
Аоп=Аbase + ss*ind
Индексният регистър (регистърът, сочен от полето index) съдържа индекса в масива. ss (scale) е число, което означава размера на елементите в масива. Ако не е фиксиран, този множител се определя по таблица 4 (Забележете образуването му: 200bin = "* 1" , 201bin = "* 2" , 210bin = "* 3", 211bin = "*8"). Адресът в различните случаи се определя по следния начин:

r/m = 100
base (3bit) адрес на 2рия операнд
mod=00 mod=01 mod=10
000 EAX + SS*ind EAX + SS*ind+d8 EAX + SS*ind + d32
001 ECX + SS*ind ECX + SS*ind+d8 ECX + SS*ind + d32
010 EDX + SS*ind EDX + SS*ind+d8 EDX + SS*ind + d32
011 EBX + SS*ind EBX + SS*ind+d8 EBX + SS*ind + d32
100 SS[ESP+SS*ind] SS[ESP +SS*ind+d8] SS[ESP+SS*ind+d32]
101 d32 + SS*ind SS[EBP + SS*ind + d8] SS[EBP + SS*ind + d32]
110 ESI + SS*ind ESI + SS*ind + d8 ESI + SS*ind + d32
111 EDI + SS*ind EDI + SS*ind + d8 EDI + SS*ind + d32
index registry
000 EAX
001 ECX
010 EDX
100
101 EBP
110 ESI
111 EDI
scale (ss) множител
00 * 1
01 * 2
10 * 4
11 * 8

таблици


При инструкциите в Pentium няма адресация тип M-M, само R-M и R-R. Втория операнд може да е в паметта и да се достъпва с косвена адресация, явна адресация, базова адресация с отместване, неявно зададен непосредствен операнд, който се запомня в полето immed.

Допълнителни четива

http://www.swansontec.com/sintel.htm

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License