Сегментная база fs
- это адрес локального хранилища потоков (по крайней мере в Linux x86-64).
.zero 8
резервирует 8 байтов нулей (предположительно в BSS).Обратитесь к руководству по GAS: https://sourceware.org/binutils/docs/as/Zero.html, ссылки в https://stackoverflow.com/tags/x86/info.
@tpoff
предположительно означают, что адрес относится к локальному хранилищу потока, вероятно, обозначает смещение потока, я не знаю.
Все остальное похоже на то, что обычно делает gcc для static
локальных переменных, которым требуется инициализатор времени выполнения: защитная переменная, которую она проверяет каждый раз, когда входит в функцию, проваливаясь в уже-инициализированный регистр.
1-байтовая защитная переменная находится в локальном хранилище потока.Фактический _
сам по себе оптимизирован, потому что он никогда не читается. Обратите внимание, что нет места для eax
после возврата foo
.
Кстати, _
- странный (плохой) выбор дляимя переменной.Легко пропустить его и, вероятно, зарезервировано для использования реализацией.
Здесь есть хорошая оптимизация: обычно (для не-локальных потоков static int var = foo();
), если он находит переменную защиты isn 't уже инициализирован, ему нужен потокобезопасный способ убедиться, что только один поток на самом деле выполняет инициализацию (по сути, берет блокировку).
Но здесь каждый поток имеет свою собственную защитную переменную (и должен запустить foo()
в первый раз, независимо от того, что делают другие потоки), поэтому не нужно вызывать функцию run_once
, чтобы получить взаимное исключение.
(извините за краткий ответ, я могупозже рассмотрим пример с https://godbolt.org/ локальной нить-нити static
и найдите SO Q & A.)