Pull to refresh

Comments 37

IncludeIGlobals ; это внутренний макрос, я не стал в нём разбираться. Если кто-то разобрался в нём то просьба рассказать.

макросы IncludeIGlobals и IncludeUGlobals вставляются все определения инициализированных и неинициализированных данных в одно место.

Благодарю!

А вот интересно, что там такого дает ассемблер что не дают языки типа Си?

отсутствие UB?

Отсутствие свободного времени?)))

На самом деле, UB тоже может иметь место :) В частности, насколько помню, команды сдвига в 8086 в некоторых случаях не совсем так же работают, как в более поздних процах (но только в экстремальных случаях -- скажем, когда счётчик числа сдвигов превосходит разрядность; но подробности за давностью лет не помню). Но по сравнению с сишным UB... :)

Ну тут все таки разные CPU... в пределах одного камня этим UB можно пренебречь :)

Вообще, это мешает переносимости: то, что работает на одной реализации архитектуры, может не работать на другой. Проблема в том, что, кажется, лишь IBM в своей Системе 360 и её потомках озаботилась дать исчерпывающие сведения о поведении машины как в нормальных, так и в "ненормальных" условиях (в том числе точно оговорила, на что можно, а на что нельзя полагаться, если нужно сохранить переносимость -- в общем, специфицировала случаи UB, только они, в отличие от С/С++, являются разумными и достаточно очевидными: скажем, если какой-то бит зарезервирован, программист должен сохранять его равным нулю, и тогда при будущих расширениях архитектуры ничего не сломается).

ЧСВ само себя не почешет :)

Пы.Сы. шутка юмора

Как иначе? "Я могу!!!" )))

Медитацию. Реально, пишешь и куда-то уплываешь в параллельный мир… фокусировка внимания такая фокусировка, ага.

Ассемблер даёт представление как всё работает внутри, ни один высокоуровневый ЯП этого не даст.

Конечно можно опустится ещё ниже, в машинный код, но это уже отдельный вид "искусства", хотя раньше этим тоже не редко занимались.

Машинный код соотносится с ассемблером 1:1.

Опуститься ещё ниже — это сделать свой процессор на FPGA.

Не совсем. На ассемблере (семейства x86) есть одни и те же команды команды которые в машинном коде могут выглядеть по разному.

А так же для знания машинного кода надо иметь больше практики чем для знания ассемблера, и вероятнее всего больше спецификации держать при себе. На ассемблере мы видим команды, на машинном языке - нет. Печатаем почти вслепую.

Дело не только в командах. На ассемблере (если сравнивать с машкодом) вы можете использовать символические имена для меток и ячеек памяти. И вам не нужно вычислять адреса либо смещение в командах перехода.

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

Шаманство, выжимание мощей из железа.

Допустим... Напиши мне switch для memcpy от 0 до 15 байт чтоб это всё генерировалось в команду аля jmp[i*align], где сами кейсы были бы выровнены по размеру кэш-линии или хотябы размера самого длинного кейса. На ассемблере такое написать как плюнуть, а на С?

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

Оптимизация вычислений.

Была одна программа на C. Писал давно. Ради интереса, решил переписать на Assembler. Сперва реализовал логику как есть, а потом открылись столько возможностей оптимизации вычислений, что код стал ощутимо меньше. Имею в виду, если сравнивать листинги. По размеру бинарника он и так будет меньше.

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

В настоящее время надо понимать, что не всегда более компактный код будет более эффективным. По этой причине делают выравнивание.

А если влезать глубже в оптимизации, то надо учитывать специфику процессора под который пишешь. Я читал Агнер Фога, где он пишет про оптимизацию. Большая часть понятна была и так. Что одни оптимизации вводятся чтоб улучшить работу кода. Кэши и прочее. Но чем дальше я читал, тем я больше понимал, что очень многое бесполезно. Одна оптимизация перекрывала другую и приводила состояние оптимизации практически к нулю.

Если сейчас идёт та же тенденция "оптимизации" процессора, то ни чего хорошего нет.

Всё что я понял, это надо просто оптимизировать код, так как лучше бы его понимала машина и постараться чтоб команды выставлялись друг за другом без зависимостей друг от друга. Например по возможности избегать кода:

mov rax, 500
add rbx, rax

и если есть возможность вставлять команды между ними которые могут быть исполнены, пока выполняется команда "mov rax, 500". Это даст дополнительную возможность выполнения параллельной команды.

Вдаваться во всё это... смысла нет, если не пишешь оптимизирующий компилятор.

Когда как. Скажем, если благодаря ручному написанию на ассемблере удастся уместиться в одну строку кэша, скорость иногда может возрасти в десятки раз -- хотя это патологический случай, конечно, но полностью исключать подобное было бы неправильно. Про зависимости по данными Вы сами написали. Плюс, программист, в отличие от компилятора, знает, что и когда действительно нужно; когда можно забить на "волатильность" данных, а когда нет, ну и т.д. -- а это может избавить от кучи лишних телодвижений. Понятно, что для ПК это почти всегда некритично, а вот на микроконтроллерах может иногда быть важным.

Да, я хотел поправить своё сообщение, но уже нельзя было. )))

Всегда надо смотреть по месту и свободному времени.

Если определённый код будет не один раз отрабатывать, то понятно дело что данный участок кода лучше оптимизировать как можно сильнее.

Я понимаю, знать ассемблер для ARM, AVR и т.д. Где действительно нужны подобные специалисты. Но на x86 - зачем?! Абсолютно бессмысленная трата времени.

Знание одного ассемблера, автоматически даёт знания другого ассемблера и изучать ассемблер под другую архитектуру становится проще. А информации как раз больше по x86-й архитектуре.

И, я оставлял ссылку, где как раз делал для ARM/ARM64/x86/x86-64 архитектур одинаковые программы.

Нет, знание кривой и убогой архитектуры x86 способно только отбить интерес к низкоуровневому программированию. "Проще" переходить с чего-нибудь более простого - Z80 или 6502.

К информации по сегментам, реальным-нереальным-долгим режимам и прочим извращениям x86 лучше вообще не притрагиваться. И это очень печально, что 90% статей по ассемблеру в рунете именно по x86 архитектуре. А больше всего - про реальный режим и 21 прерывание. Причем уже x86_64 такие авторы избегают как огня. Кроме как "ламерье" и "быдлокодинг" это никак не назвать. Сомнительно, что на подобном материале может получиться хороший системный разработчик, знающий архитектуру компьютера.

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

А вот с простой архитектуры на сложную, как раз больше проблем переходить.

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

Теперь вопрос, есть ли проблемы с документацией под x86/x86-64 архитектуры? Особенно под популярные ОС: Windows, Linux, MacOS?

Ну тогда давайте писать на Brainfuck. Или на Бейсике с номерами строк. Трудности закаляют, когда дают ценный опыт. Опыт разработки на x86 совершенно бесполезен и никак не переносится на ARM и прочее.

Относительно Windows/Linux/macOS - там все "программирование на ассемблере" сводится к вызову API-функций из системных библиотек. И документация состоит из единственной страницы, описывающей calling convention для этих функций.

Точнее вы статью не читали?

здесь я тестировал код для четырёх архитектур под Linux: Arm/Arm64/x86/x86_64.

Или вы считаете что я сразу все ассемблера под все архитектуры знал? Я так же программировал под Z80 очень давно.

Относительно Windows/Linux/macOS - там все "программирование на ассемблере" сводится к вызову API-функций из системных библиотек. И документация состоит из единственной страницы, описывающей calling convention для этих функций.

А то что для каждой архитектуры вызовы разные это учитывать не нужно? )))

То что вам не нравится какая-то определённая архитектура, ни как не значит, что этой архитектурой не должны пользоваться другие. И, если есть необходимая документация и по ассемблеру и документация к ОС, то всё что вы написали просто сводится к нулю.

Если вам просто подискутировать надо, то извините, я на этом заканчиваю, ваше мнение я услышал и оно не объективно.

Если кратко, мне не нравится засилье информации про x86 (при отсутствии необходимости в ней, т.к. все ПО, включая ядра и драйвера, пишется на C/C++) и игнорирование платформ, где действительно нужны знания ассемблера. Вместо любой статьи про x86 была бы полезнее статья про программирование микроконтроллеров.

Ту вашу статью посмотрел, вот такое и нужно. Претензия больше не к вам.

https://habr.com/ru/articles/763636/ - вот, например, очередная мусорная статья про HelloWorld для 32-битных Windows. Это так сложно - вызвать 4 раза push для передачи параметров слева направо и затем call MessageBoxA...

Это не учебный материал, это просто спам. А единственного разумного человека в комментариях, спросившего, а не лучше ли это переписать на x64, под современную архитектуру что ли, воиствующее ламерье утопило в минусах. Истинная причина, скорее всего в том, что они (как и авторы подобных статей; это не про вас, если что) это делать не умеют, про выравнивание стека не нагуглили.

По моим наблюдениям, большинство подобных ассемблерщиков деградируют в своем развитии и не уходят дальше либо реального 16-битного режима DOS, либо 32-разрядного защищенного под Windows. При этом имеют огромное ЧСВ и считают себя умнее любого Scala разработчика, проектирующего отказоустойчивые Highload системы.

Действительно ценные материалы по низкоуровневому программированию (микроконтроллеры, архитектура RTOS и др.) приходится искать на англоязычных ресурсах, а у нас гарантированно не будет ничего, кроме переводов Iczelion'а и перепечаток из Пильщикова и Зубкова. Недавно вот захотел создать свою ОС для Raspberry Pi - в рунете информации по теме ноль.

Напишите загрузчик, дальше будет проще. Насколько я знаю сейчас повсеместно используется Efi-загрузчик. Примеры как его писать есть.

При этом имеют огромное ЧСВ

А единственного разумного человека в комментариях, спросившего, а не лучше ли это переписать на x64, под современную архитектуру что ли, воиствующее ламерье утопило в минусах.

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

большинство подобных ассемблерщиков деградируют в своем развитии и не уходят дальше либо реального 16-битного режима DOS, либо 32-разрядного защищенного под Windows.

Так вот и живем, делать ничего не умеем, гуглить тоже, деградируем и пишем ассемблер под DOS, а огромное ЧСВ вовсе даже не у dkutergin )

Технологическая сингулярность. Кродеться.

Ну а кроме шуток - это тоже хобби, это тоже отдых.

Хобби - это написание демок для ZX Spectrum или создание умного дома с Arduiono. А написание ассемблерного кода для x86 в 2024 году - это шизофрения вроде Temple OS. Хобби может быть написание программ для DOS. Но нет ни одной причины, почему для этого стоит выбрать ассемблер вместо C/C++.

Если писать демки под DOS, то с ассемблером в руках получше выйдет быстродействие. А если замахнуться на sizecoding в 256 байт, то C++ вообще мимо

Если изучил один асм, перейти на другой будет весьма и весьма просто.

Sign up to leave a comment.

Articles