Почему стандартная функция & ldquo; __ libc_start_main & rdquo; не скомпилирован с дополнительным символом подчеркивания (& ldquo; _ & rdquo;)? [Дубликат]

Поддержка Unicode в PHP по-прежнему огромна. Хотя он способен преобразовывать строку ISO8859 (которая используется внутри нее) в utf8, ей не хватает возможности работать с строками unicode изначально, что означает, что все функции обработки строк будут искажать и повреждать ваши строки. Таким образом, вам нужно либо использовать отдельную библиотеку для правильной поддержки utf8, либо самостоятельно переписать все функции обработки строк.

. Легкая часть - это просто указать кодировку в заголовках HTTP и в базе данных и т. Д., Но нет что имеет значение, если ваш PHP-код не выводит допустимый UTF8. Это сложная часть, и PHP практически не помогает. (Я думаю, что PHP6 должен исправить худшее из этого, но это все еще вдалеке)

34
задан 17 June 2013 в 17:25
поделиться

3 ответа

Из Линкеры и загрузчики :

. В то время, когда UNIX была переписана на C примерно в 1974 году, у ее авторов уже были обширные библиотеки языков участников, и это было проще манипулировать именами нового C и C-совместимого кода, чем возвращаться и исправлять весь существующий код. Теперь, спустя 20 лет, код ассемблера был переписан пять раз, а компиляторы UNIX C, особенно те, которые создают объектные файлы COFF и ELF, больше не добавляют символ подчеркивания.

Подчеркивание в результатах сборки компиляции C - это просто соглашение об именах, которое возникло в качестве обходного пути.

Вне сборки в стандартной библиотеке C часто есть определенные с реализацией функции с префиксом подчеркивания до передать понятия магичности и , не касайтесь этого обычным программистам, которые наткнулись на них.

28
ответ дан Jon Purdy 28 August 2018 в 22:37
поделиться

На первый взгляд операционная система является Unix / Unix-подобным запуском на ПК. По мне, нет ничего удивительного в том, чтобы найти _printf в сгенерированном языке ассемблера. C printf - это функция, которая выполняет ввод-вывод. Поэтому драйвер kernel + должен выполнять запрошенный ввод / вывод.

Путь команд машины, принятый на любой Unix / Unix-подобной ОС, следующий:

printf (C-код) -> _printf (libc) -> trap -> kernel + driver work -> return from trap -> return from _printf (libc) -> printf complete and return -> следующая машинная инструкция в коде C

В случае с этим извлечением кода сборки, похоже, что C printf встроен компилятором, который заставил точку входа _printf быть видимой в коде сборки.

Чтобы убедиться, что C printf не получает украшенный префикс (подчеркивание в этом случае), лучше всего, если искать во всех заголовках C для _printf с помощью команды типа:

find / usr / include -name * .h -exec grep _printf {} \; -print

-1
ответ дан Bill the Lizard 28 August 2018 в 22:37
поделиться

Множество компиляторов, используемых для перевода языка C на ассемблер, а затем запустить ассемблер для создания объектного файла. Это намного проще, чем генерировать двоичный код напрямую. (AFAIK GCC все еще это делает, но у него также есть собственный ассемблер.) Во время этого перевода имена функций становятся метками в источнике сборки. Если у вас есть функция, называемая (например) ret, некоторые сборщики могут запутаться и подумать, что это инструкция, а не метка. (Например, YASM, в основном потому, что ярлыки могут появляться практически везде и не требуют двоеточия. Если вы хотите использовать метку ret, вы должны добавить $.)

Подготовить (например, подчеркивание) на сгенерированные С-метки были намного проще, чем писать собственный C-удобный ассемблер или беспокоиться о том, что метки сталкиваются с инструкциями / директивами сборки.

В наши дни сборщики и компиляторы развились немного, и большинство людей работают на уровне C или выше в любом случае. Таким образом, первоначальная необходимость манипулировать именами на C в значительной степени ушла.

5
ответ дан cHao 28 August 2018 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: