Почему библиотека glibc использует сборку

Я смотрю на эту страницу: https://sys.readthedocs.io/en/latest/doc/01_introduction.html
, где объясняется, как glibc выполняет системные вызовы.
В одном из примеров рассматривается код и показано, что последняя инструкция glibc на самом деле выполняет системный вызов (имеется в виду прерывание процессора) написана на ассемблере.. .. Так почему же часть glibc находится в сборке? Есть ли какое-то преимущество в написании этой небольшой части на ассемблере?
Кроме того, общие библиотеки во время выполнения уже скомпилированы в правильный машинный код?
Так в чем же преимущество использования двух разных языков перед компиляцией? Спасибо.


person hescobar1013    schedule 16.08.2018    source источник
comment
Компилятор не поддерживает генерацию машинного кода для прерывания процессорной части.   -  person Ross Ridge    schedule 16.08.2018
comment
Если бы это не было написано на ассемблере, какой оператор C был бы использован?   -  person Barmar    schedule 16.08.2018
comment
Почему в любом случае удивительно, что части стандартной библиотеки C реализованы на языке более низкого уровня? Все виды языков высокого уровня обычно реализуются на языках более низкого уровня. Python, Java, Ruby, Perl и многие другие относятся к этой категории.   -  person John Bollinger    schedule 16.08.2018


Ответы (2)


Ответ очень прост: поскольку C не охватывает системные вызовы (поскольку он вообще не охватывает какое-либо физическое оборудование и предпочитает выражать себя в терминах абстрактной машины), нет конструкции C, которую glibc может использовать для выполнения системы. вызов.

Кто-то может возразить, что компилятор может предоставить своего рода встроенную функцию для этого, но поскольку в Linux glibc на самом деле является частью набора инструментов компилятора (также содержит CRT), на самом деле в нем нет необходимости, glibc может выполнять эту работу.

Кроме того, последнее, но не менее важное: в современных процессорах системный вызов обычно не является прерыванием. Вместо этого это конкретная инструкция (syscall в x86_64).

person SergeyA    schedule 16.08.2018
comment
Вы имели в виду, что glibc не может использовать какую-либо конструкцию C, где у вас есть glibc, который может использовать ...? - person zwol; 16.08.2018
comment
@zwol, да, это было сверхнепонятно, спасибо, что указали на это. Перефразировал, надеюсь теперь лучше. - person SergeyA; 16.08.2018
comment
@SergeyA ... Я вижу и понимаю, что вы имеете в виду под glibc, не желая конкретно описывать какое-либо оборудование .... но, скажем так, ради обучения, что вы хотели написать функцию C для glibc для системы платформы x86 звонки, вы могли бы это сделать? Таким образом, вместо сборки в glibc вы могли бы иметь другую функцию C, которая делала бы то же самое. Я знаю, что это было бы довольно бессмысленно и все такое, но мне просто любопытно, возможно ли это вообще. Спасибо. - person hescobar1013; 16.08.2018
comment
@hescobar1013 hescobar1013 Вы можете написать кучу функций, подобных той, что находится в элементе списка 3 этого моего старого ответа, и на самом деле это именно то, что делает glibc (по историческим причинам похороненный под горой макросов) - но в теле функции есть встроенная операция сборки, и это неизбежно. - person zwol; 16.08.2018
comment
@zwol .... Спасибо за эту ссылку, этот ответ тоже был очень интересным ... так что я понимаю, в контексте glibc и gcc сборка необходима по нескольким причинам, одна из которых заключается в том, что glibc не не хочу заниматься аппаратным уровнем и быть агностиком... но ради обучения, ВНЕ glibc и gcc, возможно ли написать библиотеку C и компилятор C для платформы x86, которые могли бы отказаться от сборки? Итак, вы могли бы сделать компилятор, который понимал бы преобразование int 0x80 или что-то подобное в машинный код для выполнения системного вызова, верно? Спасибо. - person hescobar1013; 16.08.2018
comment
Существует существует syscall функция, которую могут использовать приложения [обычно предпочтительный способ обхода glibc для системных вызовов], но glibc не использует ее внутри. Системный вызов x86 может исходить из [по крайней мере] трех разных машинных инструкций [в зависимости от реализации ОС и того, что поддерживает данная архитектура/модель]: int 0x80, syscall или sysenter. Так что пусть решает библиотека. Кроме того, когда системный вызов возвращается, IIRC, аппаратный флаг x86 carry устанавливается/сбрасывается в зависимости от ошибки, поэтому каждая библиотека fnc, выполняющая системный вызов, должна обработать это, чтобы правильно установить errno [и это лучше всего сделать в asm] - person Craig Estey; 17.08.2018
comment
@hescobar Нет, оба ответа пытаются сказать вам, что вы действительно не можете. Также я не понимаю, что вы подразумеваете под glibc, не хочет заниматься аппаратным уровнем; на самом деле, он занимается всеми видами аппаратного уровня. - person zwol; 17.08.2018
comment
@CraigEstey На самом деле вы не обходите glibc, когда используете syscall; это тоже функция, экспортированная из libc.so. - person zwol; 17.08.2018
comment
@zwol Да. Я имел в виду, например, что можно обойти функцию read, используя syscall(SYS_read,...). Это необходимо для чего-то вроде gettid, у которого нет функции оболочки glibc. - person Craig Estey; 17.08.2018

Я хочу ответить на эту часть вашего вопроса:

Кроме того, общие библиотеки во время выполнения уже скомпилированы в машинный код, верно? Итак, в чем преимущество использования двух разных языков перед компиляцией?

SergeyA правильно указывает, что нет какой-либо конструкции C (даже со всеми расширениями GCC), которая заставит компилятор выдать инструкцию syscall. Это не единственное, что должна делать библиотека C, что просто не может быть написано исключительно на C: реализации setjmp и longjmp, makecontext и setcontext, код "точки входа", который вызывает main, "батут", который вы возвращаетесь, когда вы возвращаетесь из обработчика сигнала, и несколько других низкоуровневых битов требуют небольшой ручной сборки. (Упражнение: что у них общего?)

Но есть еще одна причина смешивать язык ассемблера с программой, написанной в основном на C. Это одна из нескольких реализаций memcpy для x86-64 в glibc. Это 3100 строк написанных от руки макросов на языке ассемблера и препроцессора. То, что он делает, можно выразить четырьмя строчками на языке Си. Зачем кому-то столько хлопот? Скорость. Компиляторы всегда становятся ближе, но им еще не удалось полностью превзойти человеческий мозг, когда дело доходит до выжимания каждого последнего возможного цикла из критического самого внутреннего цикла. (Стоит упомянуть, что в начале 2018 года разработчики glibc потратили уйму времени на замену написанных от руки реализаций функций math.h на языке C, потому что компиляторы уловили их, а C ремонтопригоднее.)

И все же третий ответ, который не имеет особого отношения к glibc, но часто встречается в других местах, заключается в том, что, возможно, у вас есть два разных языка в вашей программе, потому что каждый из них лучше подходит для решения вашей проблемы. Статистический язык R в основном реализован на C, но множество его математических примитивов написаны (или были, я давно не проверял) на FORTRAN, потому что FORTRAN по-прежнему является языком, на котором думают мастера численных вычислений. Оба C и FORTRAN компилируется в машинный код, и в принципе вы могли бы переписать весь FORTRAN на C, но никто этого не хочет.

person zwol    schedule 16.08.2018
comment
FORTRAN по-прежнему является языком, на котором думают специалисты по числовым вычислениям — дело не только в том, на каком языке они думают — отсутствие псевдонимов указателей в FORTRAN позволяет проводить гораздо более агрессивную оптимизацию, что часто приводит к более быстрому машинному коду. - person Employed Russian; 19.08.2018
comment
@EmployedRussian Я думаю, что в принципе вы можете получить тот же уровень оптимизации в C при осторожном использовании restrict, но в любом случае это хороший момент: научиться думать на C потребует изучения всех подобных вещей. , которые вы должны сделать на C, но не на FORTRAN, поэтому затраты на переключение даже выше, чем кажутся на первый взгляд. - person zwol; 19.08.2018