Вопрос по assembly, x86 – Для чего предназначен регистр «FS» / «GS»?

78

Итак, я знаю, какими должны быть следующие регистры и их использование:

CS = Code Segment (used for IP)

DS = Data Segment (used for MOV)

ES = Destination Segment (used for MOVS, etc.)

SS = Stack Segment (used for SP)

Но для чего предназначены следующие регистры?

FS = "File Segment"?

GS = ???

Примечание: яnot спрашивая о какой-либо конкретной операционной системе - я спрашиваю о том, для чего они предназначены для использования процессором, если что-нибудь.

Подумайте, как много мы могли бы получить с помощью регистра BS: -} Ira Baxter
Возможно, всегда трудно понять, что происходит в чужой голове, если вы не были там в то время (а я был на другом берегу, нигде рядом с командой разработчиков Intel). torek
Я всегда использовал GS в качестве «графического сегмента». :-) Brian Knoblauch
@torek: О, ха-ха, что ... я подумал "F" был за & quot; Файл & quot; хоть. Mehrdad
Насколько я знаю, F и G в этих двух ничего не значат. Просто в CPU (и в наборе команд) было место для шести определяемых пользователем регистров сегментов, и кто-то заметил, что, кроме "S" tack-сегмента, буквы "C" и "D" (код и данные) были в последовательности, поэтому "E" был "лишним" сегмент, а затем "F" и & quot; G & quot; просто вроде следовал. torek

Ваш Ответ

3   ответа
83

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

Первоначальная цель сегментных регистров состояла в том, чтобы позволить программе получить доступ ко многим различным (большим) сегментам памяти, которые должны были быть независимыми и частью постоянного виртуального хранилища. Идея была взята из1966 Операционная система Multics, что рассматривает файлы как просто адресуемые сегменты памяти. Нет BS "Открыть файл, записать запись, закрыть файл", просто "Сохранить это значение в этом виртуальном сегменте данных" с грязной страницей.

Наши текущие операционные системы 2010 года - гигантский шаг назад, поэтому их называют «Eunuchs». Вы можете только обратитьсяyour единственный сегмент пространства процесса, дающий так называемое «плоское (IMHO тупое) адресное пространство». Сегментные регистры на компьютере x86-32 все еще можно использовать для реальных сегментных регистров, но никто не потрудился (Энди Гроув, бывший президент Intel, имел довольно известную репутацию в прошлом столетии, когда он выяснил, как все эти инженеры Intel потратили энергию и его деньги, чтобы реализовать эту функцию, что никто не собирался ее использовать. Иди, Энди!)

AMD при переходе на 64-битные системы решила, что им все равно, исключат ли они Multics в качестве выбора (это благотворительная интерпретация; неоплачиваемая - они ничего не знают о Multics), и поэтому отключили общую возможность регистров сегментов в 64-битном режиме. , По-прежнему требовалось, чтобы потоки обращались к локальному хранилищу потока, и каждому потоку требовался указатель ... где-то в немедленно доступном состоянии потока (например, в регистрах) ... для потокового локального хранилища. Поскольку Windows и Linux оба использовали FSand GS (спасибо Нику за разъяснения) для этой цели в 32-битной версии, AMD решила разрешить использовать регистры 64-битных сегментов (GS и FS) по существу только для этой цели (я думаю, вы можете Заставьте их указывать в любом месте вашего пространства процессов; не знаю, может ли код приложения загрузить их или нет). Intel в их панике, чтобы не потерять долю рынка для AMD на 64 битах, и Энди, уйдя в отставку, решил просто скопировать схему AMD.

ИМХО было бы архитектурно красивее, чтобы карта памяти каждого потока имела абсолютный виртуальный адрес (например, 0-FFF), который был локальным хранилищем потока (указатель регистра [сегмента] не нужен!); Я делал это в 8-битной ОС еще в 1970-х годах, и это было очень удобно, например, иметь еще один большой стек регистров для работы.

Итак, сегментные регистры теперь похожи на ваше приложение. Они служат рудиментарной цели. Для нашей коллективной потери.

Те, кто не знает историю, не обречены ее повторять; они обречены делать что-то тупее.

@supercat: более простая, более блестящая схема, которая позволила бы им адресовать в 65536 раз больше памяти, была бы относиться к регистрам сегментов как к полному старшему 16-битному расширению младших 16 бит, что по сути то, что 286, 386 и Multics сделал.
Одна вещь, которая мне не ясна, так как эти регистры не используются в современных операционных системах, будут ли они бесплатными для общего пользования?
Эти регистрыare используется в современных операционных системах. Они в основном предназначены для указания на информацию о блоках управления задачами, по крайней мере, в двух основных ОС, доступных сейчас для чипов x86. И, поскольку они больше не являются "универсальными" даже для их первоначального намерения вы не можете использовать их много. Лучше делать вид, что в системах x86-64 их просто не существует, пока вам не понадобится информация, к которой они предоставляют доступ в блоках управления потоками.
Сегментация 8086 была блестящей. Я не знаю лучшей схемы, позволяющей машине с данным размером регистра получать доступ к эффективному адресному пространству в 16 раз больше. Даже сегодня сегментация в стиле 8086 (но с 32-разрядным регистром сегментов, смещенным и добавленным к 32-разрядному смещению) может быть лучше, чем линейная адресация, позволяя 32-разрядным ссылкам на объекты получать доступ к 64 ГБ адресного пространства. С некоторыми небольшими изменениями полезный диапазон ссылок на 32-битные объекты может быть расширен еще больше.
@IraBaxter: Проблема с этим подходом состоит в том, что сегменты в стиле 80286 имеют достаточно высокие издержки, чем один, и в итоге приходится хранить много объектов в каждом сегменте и, таким образом, хранить как сегмент, так и смещение для каждого указателя. Напротив, если кто-то желает округлить выделения памяти до кратных 16 байт, сегментация в стиле 8086 позволяет использоватьsegment alone как средство идентификации объекта. Округление выделения до 16 байт могло бы быть немного утомительным в 1980 году, но сегодня это было бы выигрышом, если бы уменьшило размер каждой ссылки на объект с 8 байт до четырех.
4

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

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

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

mov    eax,gs:0x14
mov    DWORD PTR [ebp-0xc],eax
@MichaelPetch Да, я знаю, я просто хочу добавить это как полезную информацию для тех, кто читает эти вопросы в SO
Это на самом деле не отвечает на вопрос. Вопрос гласитNote: I'm not asking about any particular operating system -- I'm asking about what they were intended to be used for by the CPU, if anything.
38

FS а такжеGS являются сегментными регистрами. Они не имеют определенной для процессора цели, а вместо этого задаются целью операционной системой, в которой они работают. В Windows 64-bitGS регистр используется для указания на структуры, определенные операционной системой.FS а такжеGS обычно используются ядрами ОС для доступа к поточной памяти. В окнахGS регистр используется для управления памятью потока. Ядро Linux используетGS для доступа к памяти процессора.

Это не только в Windows. GS также используется для TLS на OS X. GS также используется 64-битными ядрами для отслеживания структур системы во время переключения контекста. ОС будет использовать SWAPGS для этого.
На Windows FS действительно для потокового хранилища. Смотрите документированную карту блока, указанного FS здесьen.wikipedia.org/wiki/Win32_Thread_Information_Block
Были ли они предназначены для использования в целях ОС или для облегчения кода, который должен делать что-то вроде*dest++ = lookup[*src++]; в противном случае было бы довольно неловко, если бы dest, lookup и src находились в трех не связанных друг с другом местах.

Похожие вопросы