Чтобы на самом деле ответить на ваш fs:0
вопрос: ABI x86_64 требует, чтобы fs:0
содержал адрес, «указанный» самим fs
.То есть fs:-4
загружает значение, хранящееся в fs:0 - 4
.Эта функция необходима, потому что вы не можете легко получить адрес, на который указывает fs
, не пройдя код ядра.Таким образом, хранение адреса в fs:0
делает работу с локальным хранилищем потока более эффективной.
Это можно увидеть в действии, когда вы берете адрес локальной переменной потока:
static __thread int test = 0;
int *f(void) {
return &test;
}
int g(void) {
return test;
}
компилируется в
f:
movq %fs:0, %rax
leaq -4(%rax), %rax
retq
g:
movl %fs:-4, %eax
retq
i686 делает то же самое, но с %gs
.На aarch64 это не обязательно, потому что адрес можно прочитать из самого регистра tls.