LINUX.ORG.RU

Как кодируется русский текст в ассемблере?

 ,


1

1

В ассемблерном коде есть такие строки:

.string	"\320\224\320\265\320\273\320\270\320\274 \320\275\320\260\320\264\320\262\320\276\320\265, \321\200\320\265\320\267\321\203\320\273\321\214\321\202\320\260\321\202: "

В исходнике на С++ это строки на русском. Но я не пойму, что это за кодировка в ассемблере. Онлайн-декодеры фейлятся в определении и расшифровке.

что это за кодировка в ассемблере

Вот то что ты предоставил в стартовом посте это просто вариант представления данных в Octet String, но кодировка там может быть любой:

$ printf "\320\224\320\265\320\273\320\270\320\274"
Делим

В данном случае там ставший дефолтным в UNIX-like операционных системах UTF-8.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 3)

Компилятор просто заэкранировал non-ASCII символы на всякий случай (подозреваю можно было это и не делать и оставить как есть). 320 223 320 это значения байтов в восьмеричной системе. В Си так тоже можно писать.

Из кодировок что в асме, что в Си, есть только ASCII (7-битное) - оно используется для синтаксиса. А внутри кавычек просто байтовые блобы, которые напрямую кочуют в бинарник после разбора экранирований (ну там \n заменяется на перевод строки, а \320 на байт 0320).

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
>>> chr(0o2024) + chr(0o2065) + chr(0o2073) + chr(0o2070)+ chr(0o2074)
'Делим'
>>> chr(0o2075) + chr(0o2060) + chr(0o2064) + chr(0o2062)+ chr(0o2076)+ chr(0o2065)
'надвое'
>>>

«Визуальный» алгоритм получения кодепойнтов для кириллицы очень простой.

vM ★★
()
Ответ на: комментарий от EXL

Зацени, кстати, как расшифровал это слово чатгпт 😆

Конечно, данный текст выглядит как последовательность чисел, представленных в восьмеричной системе счисления. Если преобразовать эти числа в символы Unicode согласно указанным восьмеричным значениям, мы получим следующий текст:

"Привет, регулярные выражения, тестирование:"
alex1101
() автор топика
Ответ на: комментарий от alex1101

Да вроде как нет там ничего мудрёного, вместо HEX просто представление OCT используется:

$ echo "Делим" | od -b
0000000 320 224 320 265 320 273 320 270 320 274 012
0000013

$ echo "Делим" | hd
00000000  d0 94 d0 b5 d0 bb d0 b8  d0 bc 0a                 
0000000b

А вот почему оно используется в компиляторах, когда HEX намного компактнее и стандартнее – это уже другой вопрос.

EXL ★★★★★
()
Ответ на: комментарий от EXL

А вот почему оно используется в компиляторах, когда HEX намного компактнее и стандартнее – это уже другой вопрос.

Возможно, потому что это собрано с -Og -S? Если собрать с -O2 и потом дизассемблировать через objdump -d - получается совсем другой листинг, без вот этих вот октетов.

alex1101
() автор топика
Ответ на: комментарий от alex1101

Ну, да, типичный ChatGPT.

У меня аналогичные случаи были, выдумал сука какую-то библиотеку для решения моей проблемы, я её искал два часа, а её и не существовало никогда.

Пытался ещё юзать ChatGPT в плане «посоветуй книгу про <что-то>», так он тоже выдумывает (причём правдаподобно) никогда не существовавшие произведения и их названия.

Ну а факт-чекинг у него хуже чем у гугла, откровенную дезу пишет и не краснеет:

The first phone with Java support was the Nokia 6110 released in 1997. It was one of the earliest mobile phones to support Java ME (Micro Edition), which allowed users to download and run small Java-based applications and games on their devices.

Такое ощущение что в собственном манямирке обитает.

EXL ★★★★★
()
Ответ на: комментарий от alex1101

Причём тут сборка? Это просто один из вариантов человекоудобного бдампа байтовой последовательности. В бинарниках никакого текстового формата дампов нет, там, сами байты уже, как objdump захочет так и сдампит их в текстовый вид.

firkax ★★★★★
()
Ответ на: комментарий от alex1101

Возможно, потому что это собрано с -Og -S? Если собрать с -O2 и потом дизассемблировать через objdump -d - получается совсем другой листинг, без вот этих вот октетов.

Если ты -O2 -S попробуешь, то там наверняка тоже будут эти октеты. Листинг по -S и objdump -d всегда будет разным, поскольку в первом случае это просто выхлоп оптимизирующего компилятора без последующего ассемблирования в машкод и линковки, а во втором случае это уже декомпилирование исполняемого файла где всё уже разложено по секциям, строчка будет в какой-нибудь .rodata, применены LTO (Link Time Optimization) и т. д.

EXL ★★★★★
()
Ответ на: комментарий от EXL

Ты написал какую-то ерунду. Что значит «используется в компиляторах»? Почему «компактнее»?

1) си -> асм конвертатор сдампил строку в oct в первую очередь потому что так исторически принято (ещё из 50-60-х годов до того как Си появился, восьмеричное использовалось намного чаще шестнадцатиричного, по причине большей понятности людям). Во вторую очередь - см. пункт 2.

2) Нет, hex не компактнее, hex это обычно \xHH - те же 4 символа, но у него есть большой недостаток - «\x012» это тоже валидная hex-последовательность по стандарту Си, и «\x0012» - тоже, и таким образом последующие неэкранированные цифры могут испортить дамп, если не принять мер. А у восмеричного экранирование используется строго 3 цифры, то есть «\0012» это символ '\001' и символ '2'.

firkax ★★★★★
()
Ответ на: комментарий от firkax

человекоудобного

В каком месте? Человекоудобным был бы:

.string	"\xd0\x94\xd0\xb5\xd0\xbb\xd0\xb8\xd0\xbc\x0a"

А не эта дичь оставшаяся там по каким-то историческим причинам и несуразицам. Кто в здравом уме будет что-то высчитывать в октетах в 2024 году? Ты вот, к примеру, помнишь что максимальное значение байта в OCT это Oo377, а не привычное всем в HEX – 0xFF?

Это просто какая-то историческая наркомания разработчиков GCC.

Октеты только в одном месте действительно удобны – chmod 0755 и иже с ними.

EXL ★★★★★
()
Ответ на: комментарий от EXL

строчка будет в какой-нибудь .rodata, применены LTO (Link Time Optimization) и т. д.

Оптимизация ни при чём, отличие лишь в привычках авторов gcc и авторов objdump, первым нравятся восьмеричные дампы а вторые видимо предпочитают писать как есть. ВОзможно это настраивается какими-то опциями.

firkax ★★★★★
()
Ответ на: комментарий от EXL

Человекоудобного - это значит что ты увидишь не какую-то непонятную закорючку от шрифта для символа с номером 17, а увидишь что-то что можно понять. В каком это будет виде (шестнадцаричном \x11, восьмеричном \021 или десятичном chr(17) или #17 номере символа, или же последовательность ^Q, символизирующая тот факт, что этот символ можно набрать как Ctrl-Q) - уже отдельный вопрос и зависит от предпочтений.

Ты вот, к примеру, помнишь что максимальное значение байта в OCT это Oo377, а не привычное всем в HEX – 0xFF?

Разумеется. Только 0o377 никто не пишет обычно, хотя и выглдяит логично, пишут 0377 занятое ещё в древние времена.

Октеты

Октет - это почти синоним к слову байт (8 бит). А восьмеричное представление никаким коротким словом не называется.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от firkax

исторически принято

Когда где-то имеется приписка «так сложилось исторически», значит на выходе будет неудобная и слабоюзабельная дрянь, этот тред как раз ещё одна яркая демонстрация, потдверждающяя это.

«\x012» это тоже валидная hex-последовательность по стандарту Си, и «\x0012»

То что в стандартах C и C++ налито говно известно всем походившим по многочисленным UB. Все эти нелогичности бы тут же убрались, если бы escape-последовательность \x ожидала далее ровно два символа в диапазоне 0-F.

Вот потому в новых языках и новых стандартах вводят всякие u8 и u8R, потому что наркоманские дидовские октеты максимально неудобны и путают, а ещё плодят чёртовы уязвимости (вспоминается какой-то там Zero-Day из-за оставленного октетного нуля в сишной либе).

https://en.cppreference.com/w/cpp/language/string_literal

EXL ★★★★★
()
Ответ на: комментарий от EXL

То что в стандартах C и C++ налито говно известно всем походившим по многочисленным UB. Все эти нелогичности бы тут же убрались, если бы escape-последовательность \x ожидала далее ровно два символа в диапазоне 0-F.

Да, есть такое, но это тоже исторически сложилось и ломать уже нельзя - так очень легко незаметно нарушить работу старого кода - он может продолжать компилироваться без ошибок, но станет тайком неправильно работать (и хорошо если речь только про текстовые строки для юзера, а не про дампы каких-то побайтово важных структур), и виноваты в этом будут исключительно авторы компилятора.

В любом случае, оно будет 4 символа как и oct и удобство только в привычности.

firkax ★★★★★
()
Ответ на: комментарий от EXL

Вот потому в новых языках и новых стандартах вводят всякие u8 и u8R, потому что наркоманские дидовские октеты максимально неудобны и путают

Но ведь u8 и u8R вообще не про кодирование непечатных символов…

i-rinat ★★★★★
()