Для чого призначений реєстр “FS” / “GS”?


102

Тому я знаю, якими мають бути наступні регістри та їх використання:

  • CS = сегмент коду (використовується для IP)

  • DS = сегмент даних (використовується для MOV)

  • ES = Сегмент призначення (використовується для MOVS тощо)

  • SS = сегмент стека (використовується для SP)

Але для чого призначені наступні регістри?

  • FS = "Сегмент файлу"?

  • GS = ???

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


24
Наскільки мені відомо, F і G у цих двох не означають нічого. Просто в центральному процесорі (і в наборі інструкцій) було місце для шести специфічних користувачем регістрів сегментів, і хтось помітив, що крім сегмента прикріплення "S", літери "C" і "D" (код і дані) йшли послідовно, тому "E" було "зайвим" сегментом, а потім "F" і "G" просто начебто слідували.
torek

3
Могло бути, завжди важко зрозуміти, що відбувалося в чужій голові, якщо ти не був там у той час (а я був на іншому узбережжі, ніде не поруч із дизайнерською командою Intel).
Торек

20
Подумайте лише, скільки ми могли б отримати задоволення від реєстрації BS: -}
Ira Baxter

5
Я завжди використовував GS як "графічний сегмент". :-)
Брайан Ноблауч,

2
Як щодо "G" загального "S" елементу?
SS Anne

Відповіді:


109

Існує те, для чого вони були призначені, і для чого вони використовуються в Windows та Linux.

Початковий намір регістрів сегментів полягав у тому, щоб дозволити програмі отримати доступ до багатьох різних (великих) сегментів пам'яті, які мали бути незалежними та частиною постійного віртуального сховища. Ідея була взята з операційної системи Multics 1966 року , яка обробляла файли як просто адресовані сегменти пам'яті. Немає BS "Відкрити файл, записати запис, закрити файл", просто "Зберегти це значення у цьому віртуальному сегменті даних" з очищенням брудної сторінки.

Наші поточні операційні системи 2010 року - це гігантський крок назад, саме тому їх називають "євнухами". Ви можете звернутися лише до одного сегменту вашого процесу, надавши так званий "плоский (нульовий) адресний простір IMHO". Реєстри сегментів на машині x86-32 все ще можна використовувати для справжніх регістрів сегментів, але ніхто не турбував (Енді Гроув, колишній президент Intel, мав досить відомий загальнодоступний стан в минулому столітті, коли з’ясував, що після того, як усі ці інженери Intel витратили енергію і його гроші на реалізацію цієї функції, щоб ніхто не збирався нею користуватися. Іди, Енді!)

AMD, перейшовши до 64 біт, вирішив, що їм байдуже, якщо вони усунуть Multics як вибір (це благодійна інтерпретація; недоброзичлива - вони не знають про Multics) і тому відключили загальну можливість сегментних регістрів у 64-бітному режимі. Все ще існувала потреба в потоках для доступу до локального сховища потоків, і для кожного потоку потрібен був вказівник ... десь у безпосередньо доступному стані потоку (наприклад, у регістрах) ... для потокового локального сховища. Оскільки і Windows, і Linux використовували для цієї мети FSand GS (дякую Ніку за роз'яснення) у 32-бітовій версії, AMD вирішила дозволити 64-бітові регістри сегментів (GS та FS) використовуватись по суті лише для цієї мети (я думаю, ви можете змусьте їх вказувати де завгодно у вашому робочому просторі; не знаю, чи може код програми завантажити їх чи ні).

Було б кращим в архітектурному відношенні IMHO, щоб карта пам'яті кожного потоку мала абсолютну віртуальну адресу (наприклад, 0-FFF, скажімо), яка була локальним сховищем її потоку (не потрібен вказівник [сегмента] реєстру!); Я зробив це в 8-розрядної ОС ще в 1970-х роках, і це було надзвичайно зручно, як наявність ще одного великого стопки регістрів, в якому можна працювати.

Отже, регістри сегментів зараз схожі на ваш додаток. Вони служать рудиментарній меті. До нашої колективної втрати.

Ті, хто не знає історії, не приречені її повторювати; вони приречені робити щось дурніше.


10
@supercat: Більш проста, блискуча схема, яка дозволила б їм адресувати в 65536 разів більше пам’яті, полягала б у тому, щоб трактувати регістри сегментів як повне верхнє 16-бітове розширення нижчих 16 бітів, що, по суті, і є те, що 286, 386 і Multics зробили.
Ira Baxter,

3
@IraBaxter: Проблема такого підходу полягає в тому, що сегменти в стилі 80286 мають достатньо високі накладні витрати, ніж в кінцевому підсумку потрібно зберігати багато об’єктів у кожному сегменті, і таким чином зберігати як сегмент, так і зміщення на кожному покажчику. На відміну від цього, якщо хтось бажає округлити розподіли пам’яті до кратних 16 байт, сегментація у стилі 8086 дозволяє використовувати сегмент окремо як засіб ідентифікації об’єкта. Виділення округлень до 16 байт могло б бути трохи неприємним у 1980 році, але сьогодні представляло б виграш, якби зменшило розмір кожного посилання на об'єкт з 8 байт до чотирьох.
supercat

3
Ці регістри будуть використані в сучасних операційних системах. Вони в основному присвячені вказуванню інформації про блоки управління завданнями, принаймні в двох основних ОС, які зараз доступні для мікросхем x86. І оскільки вони більше не є "загальним призначенням" навіть за їх початковим задумом, ви не можете їх багато використовувати. Краще робити вигляд у системах x86-64, що їх просто не існує, поки вам не знадобиться інформація, яку вони дозволяють вам отримати в блоках управління потоками.
Ira Baxter

5
Аналогія додатка насправді погана, базуючись на застарілій науці; це пов’язано з імунною системою, тому однозначно не “рудиментарно”. Це погіршує фактичну посаду. Крім цього, це хороший відгук.
code_dredd

5
Дякуємо за смішне, заборонене лікування сегментованої та плоскої пам’яті :) Написавши також код на 6809 (з і без підкачувальної пам’яті), 6502, z80, 68k та 80 [123]? 86, моя думка така пам’ять - це шоу жахів, і я радий, що воно було передане на смітник історії. Використання FS та GS для ефективного доступу до даних thread_local є щасливим ненавмисним наслідком історичної помилки.
Річард Ходжес,

44

Регістри FSі GSє сегментними регістрами. Вони не мають визначеного процесором призначення, але натомість їх призначає ОС, що їх запускає. У Windows 64-розрядної версії GSрегістр використовується для вказівки на структури, визначені операційною системою. FSі GSзазвичай використовуються ядрами ОС для доступу до певної пам’яті. У вікнах GSрегістр використовується для управління потоковою пам’яттю. Ядро Linux використовує GSдля доступу до спеціальної пам'яті процесора.


1
Чи були вони призначені для використання для цілей, визначених ОС, або для полегшення коду, який повинен робити щось подібне, *dest++ = lookup[*src++];що в іншому випадку було б досить незручним, якби dest, пошук та src знаходились у трьох не пов'язаних між собою місцях.
supercat

8
У Windows FS справді призначений для спеціального сховища. Дивіться задокументовану карту блоку, на яку вказує ФС тут en.wikipedia.org/wiki/Win32_Thread_Information_Block
Недко

2
Це стосується не лише Windows. GS також використовується для TLS в OS X. GS також використовується 64-бітними ядрами для відстеження системних структур під час перемикання контексту. ОС буде використовувати SWAPGS для цього.
ET

12

FS використовується для вказівки на інформаційний блок потоку (TIB) у процесах Windows.

типовим прикладом є ( SEH ), який зберігає вказівник на функцію зворотного виклику в FS:[0x00].

GS зазвичай використовується як вказівник на локальне сховище потоків (TLS). і одним із прикладів, який ви могли бачити раніше, є захист канарки стека (stackguard), у gcc ви можете побачити щось подібне:

mov    eax,gs:0x14
mov    DWORD PTR [ebp-0xc],eax

2
Це насправді не відповідає на питання. У запитанні зазначено Примітка: Я не запитую про якусь конкретну операційну систему - я запитую про те, для чого їх призначив центральний процесор, якщо що.
Michael Petch

9
@MichaelPetch ya, я знаю, що я просто хочу додати це як гарну інформацію для тих, хто читає ці
запитання

2

Згідно з Посібником Intel, у 64-розрядному режимі ці регістри призначені для використання як додаткові базові регістри в деяких лінійних розрахунках адрес. Я витягнув це з розділу 3.7.4.1 (стор. 86 у наборі з 4 томів). Зазвичай, коли центральний процесор знаходиться в цьому режимі, лінійна адреса є такою ж, як ефективна адреса, оскільки сегментація часто не використовується в цьому режимі.

Отже, у цьому просторовому адресному просторі FS & GS відіграють роль у вирішенні не просто локальних даних, а певних структур даних операційної системи (стор. 2793, розділ 3.2.4), отже ці регістри були призначені для використання операційною системою, однак ці конкретні розробники визначити.

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

З точки зору "оригінальних намірів", важко сказати, що це лише додаткові регістри. Коли центральний процесор знаходиться в режимі реальної адреси , це схоже на те, що процесор працює на високошвидкісному 8086, і програма повинна мати явний доступ до цих регістрів. Задля справжньої емуляції 8086 ви б запускали центральний процесор у режимі віртуального 8086, і ці регістри не використовуватимуться.


2

TL; DR;

Для чого призначений реєстр “FS” / “GS”?

Просто отримати доступ до даних поза сегментом даних за замовчуванням (DS). Точно як ES.


Довге читання:

Тому я знаю, якими мають бути наступні регістри та їх використання:

[...]

Ну, майже, але DS - це не "якийсь" сегмент даних, а стандартний. Якщо всі операції відбувалися за замовчуванням (* 1). Це були всі змінні за замовчуванням - по суті dataта bss. Це певним чином частина причини, чому код x86 є досить компактним. Усі основні дані, до яких найчастіше отримують доступ (плюс код та стек), знаходяться в межах 16-бітової скороченої відстані.

ES використовується для доступу до всього іншого (* 2), до всього, що перевищує 64 КБ DS. Подібно до тексту текстового процесора, комірок розгорнутого аркуша або даних зображень графічної програми тощо. На відміну від часто передбачуваного, доступ до цих даних не надто великий, тому необхідність префіксу шкодить менше, ніж використання довших полів адрес.

Подібно, це лише незначна неприємність, що DS і ES, можливо, доведеться завантажувати (і перезавантажувати) під час виконання рядкових операцій - це, принаймні, компенсується одним з найкращих наборів інструкцій обробки символів свого часу.

Що насправді шкодить, це те, коли користувацькі дані перевищують 64 КіБ і операції повинні починатися. Хоча деякі операції просто виконуються з одним елементом даних за раз (подумайте A=A*2), більшості потрібні два ( A=A*B) або три елементи даних ( A=B*C). Якщо ці елементи знаходяться в різних сегментах, ES буде перезавантажуватися кілька разів за операцію, додаючи досить багато накладних витрат.

На початку, з невеликими програмами з 8-бітного світу (* 3) і настільки ж малими наборами даних, це не було великою проблемою, але незабаром це стало великим продуктивним горлом - і тим більше справжнім болем у дупі для програмісти (і компілятори). З 386 Intel нарешті отримав полегшення, додавши ще два сегменти, тому будь-яка серія одинарних , двійкових або потрійних операцій з елементами, розподіленими в пам’яті, може відбуватися без постійного перезавантаження ES.

Для програмування (принаймні в збірці) та дизайну компілятора це було суттєвим виграшем. Звичайно, могло бути навіть більше, але з трьома горловиною пляшки в основному не було, тому не потрібно перестаратися.

Назви мудрі букви F / G - це просто алфавітні продовження після Е. Принаймні з точки зору процесора нічого не пов'язано.


* 1 - Використання ES для призначення рядків є винятком, оскільки потрібні просто два сегментні регістри. Без них вони не були б дуже корисними - або завжди потребували префікса сегмента. Що може вбити одну з дивовижних особливостей, використання (неповторюваних) рядкових інструкцій, що призводить до надзвичайної продуктивності завдяки кодуванню одного байта.

* 2 - Отже, заднім числом "Все інше сегмент" було б набагато кращим іменом, ніж "зайвий сегмент".

* 3 - Завжди важливо мати на увазі, що 8086 задумувався лише як запобіжний зазор, поки 8800 не був закінчений, і головним чином призначений для вбудованого світу для утримання клієнтів 8080/85 на борту.


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