Какова цель этого сегмента кода из glibc

Я пытаюсь понять, что делает следующий сегмент кода из tls.h в glibc и почему:

/* Macros to load from and store into segment registers.  */
# define TLS_GET_FS() \
  ({ int __seg; __asm ("movl %%fs, %0" : "=q" (__seg)); __seg; })

Я думаю, что понимаю основную операцию, это перемещение значения, хранящегося в fs зарегистрироваться в __seg, Однако у меня есть несколько вопросов:

  1. Мое понимание fs только 16 бит. Это правильно? Что происходит, когда значение перемещается в область памяти четырех слов? Означает ли это, что верхние биты установлены в 0?

  2. Более важно, я думаю, что область действия переменной __seg то, что объявлено в начале сегмента, ограничено этим сегментом. Так как же __seg полезно? Я уверен, что авторы glibc У меня есть веская причина для этого, но я не могу понять, что это, посмотрев на исходный код.

Я попытался создать сборку для этого кода, и я получил следующее?

 #APP
 # 13 "fs-test.cpp" 1
 movl %fs, %eax
 # 0 "" 2
 #NO_APP

Так в моем случае это выглядит eax был использован для __seg, Но я не знаю, так ли это всегда, или это было то, что произошло в небольшом тестовом файле, который я скомпилировал. Если это всегда будет использовать eax почему сборка не будет написана таким образом? Если компилятор может выбрать другие регистры, то как программист узнает, к какому из них обращаться? __seg выходит из области видимости в конце макроса? Наконец, я не видел, чтобы этот макрос использовался где-либо, когда я нашел его в исходном коде glibc, так что это еще больше увеличивает путаницу в том, какова его цель. Любое объяснение того, что делает код, и почему ценится.

1 ответ

Решение

Насколько я понимаю, фс только 16 бит. Это правильно? Что происходит, когда значение перемещается в область памяти четырех слов? Означает ли это, что верхние биты установлены в 0?

Да.

переменная __seg, которая объявляется в начале сегмента, ограничена этим сегментом. Так чем же полезен __seg?

Вы должны прочитать о расширении выражения оператора GCC. Значением выражения выражения является значение последнего выражения в нем. __seg; в конце было бы бесполезно, если не назначить это кому-то еще, например так:

int foo = TLS_GET_FS();

Наконец, я не видел, чтобы этот макрос использовался нигде, когда я нашел его в исходном коде glibc.

TLS_{GET,SET}_FS на самом деле, кажется, не используются. Они, вероятно, использовались в какой-то версии, а затем случайно остались, когда код, ссылающийся на них, был удален.

Другие вопросы по тегам