Какова цель этого сегмента кода из 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
, Однако у меня есть несколько вопросов:
Мое понимание
fs
только 16 бит. Это правильно? Что происходит, когда значение перемещается в область памяти четырех слов? Означает ли это, что верхние биты установлены в 0?Более важно, я думаю, что область действия переменной
__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
на самом деле, кажется, не используются. Они, вероятно, использовались в какой-то версии, а затем случайно остались, когда код, ссылающийся на них, был удален.