Призначення регістрів ESI та EDI?


119

Яке власне призначення та використання регістрів EDI та ESI в асемблері?

Я знаю, що вони використовуються для рядкових операцій для однієї речі.

Чи може хтось також навести приклад?


9
Перевірте це: swansontec.com/sregisters.html
Jeffpowrs

Відповіді:


78

Є кілька операцій, які ви можете виконати лише з DI / SI (або їх розширеними аналогами, якщо ви не вивчили ASM в 1985 році). Серед них є

REP STOSB
REP MOVSB
REP SCASB

Які, відповідно, операції для повторного (= масового) зберігання, завантаження та сканування. Що ви робите, ви налаштовуєте SI та / або DI так, щоб вони вказували на один або обидва операнди, можливо, ставили підрахунок у CX, а потім дозволяли 'er rip. Це операції, які працюють над купою байтів одночасно, і вони начебто ставлять процесор автоматичним. Оскільки ви чітко не кодуєте петлі, вони роблять свою справу ефективніше (як правило), ніж цикл, кодований вручну.

На випадок, якщо вам цікаво: залежно від того, як ви налаштували операцію, повторне зберігання може бути чимось простим, як пробивання значення 0 у великий суміжний блок пам'яті; MOVSB ​​використовується, я думаю, для копіювання даних з одного буфера (ну, будь-який пакет байтів) в інший; і SCASB використовується для пошуку байта, який відповідає якомусь критерію пошуку (я не впевнений, чи це пошук лише на рівності, або що - ви можете це шукати :))

Це найбільше те, для чого ці регресні.


7
Порада з оптимізації з минулого: rep stosw набагато швидше, ніж rep stosb , тому якщо копіювання двох та двох байтів відповідає тому, що ви намагаєтесь зробити, використовуйте це замість цього в 16-бітовому коді збірки x86, зібраного вручну ...
Олександр

88

SI= Індекс джерела
DI= Індекс призначення

Як зазначали інші, вони мають спеціальне використання з рядковими інструкціями. Для реального програмування режиму, то ESрегістр сегмента повинен бути використаний з , DIі DSз , SIяк і в

movsb  es:di, ds:si

SI та DI можуть також використовуватися як регістри індексів загального призначення. Наприклад, Cвихідний код

srcp [srcidx++] = argv [j];

компілює в

8B550C         mov    edx,[ebp+0C]
8B0C9A         mov    ecx,[edx+4*ebx]
894CBDAC       mov    [ebp+4*edi-54],ecx
47             inc    edi

де ebp+12містить argv, ebxє jі ediмає srcidx. Зверніть увагу, що третя інструкція використовує ediмножинне значення 4 і додає ebpзміщення на 0x54 (розташування srcp); дужки навколо адреси вказують на непрямість.


Хоча я не можу згадати, де я це бачив, але це підтверджує більшість із цього, і це (слайд 17) інші:

AX= акумулятор
DX= подвійний акумулятор слів
CX= лічильник
BX= базовий регістр

Вони схожі на регістри загального призначення, але є ряд інструкцій, які (несподівано?) Використовують один із них, але який?


37

Такі коди, як MOVSB ​​і MOVSW, які ефективно копіюють дані з пам'яті, на яку вказує ESI, в пам'ять, на яку вказує EDI. Таким чином,

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!

12

На додаток до рядкових операцій (MOVS / INS / STOS / CMPS / SCASB / W / D / Q тощо), зазначених в інших відповідях, я хотів би додати, що існують також більш "сучасні" інструкції щодо монтажу x86, які неявно використовуються в найменше EDI / RDI:

Інструкція SSE2 MASKMOVDQU(і майбутня AVX VMASKMOVDQU) вибірково записує байти з регістра XMM в пам'ять, на яку вказує EDI / RDI.


6

На додаток до регістрів, які використовуються для масових операцій, вони корисні тим, що вони зберігаються за допомогою виклику функції (збереження виклику) у 32-розрядному режимі виклику. ESI, EDI, EBX, EBP, ESP зберігаються при виклику, тоді як EAX, ECX і EDX не зберігаються. Записи збережених викликів дотримуються функції бібліотеки С, а їх значення зберігаються через виклики функції бібліотеки С.

Джефф Дантеманн у своїй книзі з мовою збірки має приклад коду складання для друку аргументів командного рядка. Код використовує esi та edi для зберігання лічильників, оскільки вони будуть незмінними функцією бібліотеки C printf. Для інших реєстрів, таких як eax, ecx, edx, немає гарантії, що вони не будуть використані функціями бібліотеки C.

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

Див. Розділ 12.8 Як C бачить аргументи командного рядка.

Зауважте, що 64-розрядні конвенції викликів відрізняються від 32-бітових конвенцій викликів, і я не впевнений, зберігаються вони чи ні.


Я ніколи не чув "священного", що використовується для опису того, що більшість людей називає "непостійним" / "енергонезалежним", або "врятованим коллегом" проти "врятованим". Мені подобаються "збережені виклики" / "халотні дзвінки", оскільки це не означає, що вони насправді зберігаються деінде. У будь-якому разі, ESI / RSI та EDI / RDI не зберігаються у виклику в x86-64 System V ABI.
Пітер Кордес

Крім того, ви забули вказати EBP та ESP як збережені виклики у загальних 32-бітних конвенціях про виклики.
Пітер Кордес

1
У всякому разі, це досить непоганий момент. У фактичному коді ви більше шансів обрати EDI / ESI з чогось, що ґрунтується на причинах виклику, ніж через те, що вони спеціальні для будь-яких інструкцій.
Пітер Кордес

Мені подобається збереження дзвінків. Я оновив відповідь тим самим. Дякуємо за відгук.
Джей Раджпут
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.