Я программирую на языках более высокого уровня (Python, C #, VBA, VB.NET) около 10 лет, и у меня совершенно нет понимания того, что происходит, «под капотом».
Мне интересно, каковы преимущества обучения ассемблеру, и как это поможет мне как программисту? Не могли бы вы предоставить мне ресурс, который точно покажет мне связь между тем, что я пишу в коде более высокого уровня, и тем, что происходит в сборке?
for
цикл, объявляя переменные вне его. примерОтветы:
Потому что вы поймете, как это действительно работает.
Все сводится к тому, что все, что мы пишем на C # или Python, необходимо преобразовать в последовательность основных действий, которые может выполнять компьютер. Легко представить компьютер с точки зрения классов, обобщений и составления списков, но они существуют только в наших языках программирования высокого уровня.
Мы можем думать о языковых конструкциях, которые выглядят действительно хорошо, но не очень хорошо переводят на низкоуровневый способ работы. Зная, как это действительно работает, вы лучше поймете, почему все работает так, как они работают.
источник
Это даст вам лучшее понимание того, что «происходит изнутри» и как работают указатели, а также значения переменных реестра и архитектуры (распределение памяти и управление ею, передача параметров (по значению / по ссылке) и т. Д.) В целом.
Для быстрого взгляда с C как это?
скомпилируйте
gcc -S so.c
и посмотрите на вывод сборки вso.s
:источник
so.c
файл для вопросов stackoverflow (как у меня естьso.py
, иso.awk
т. Д.), Чтобы быстро проверить вещи. So.S .. :)gcc -O -c -g -Wa,-ahl=so.s so.c
вы увидите выходные данные сборки для каждой строки кода C. Это немного облегчает понимание того, что происходит.5:so.c
чтобы найти код для строки 5 изso.c
.Я думаю, что вы ищете ответ здесь: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language
Цитата из статьи:
Кроме того, я бы порекомендовал эту книгу, потому что она имеет упрощенную версию компьютерной архитектуры: Введение в вычислительные системы: от битов и гейтов до Си и далее, 2 / е Йель Н. Патт, Техасский университет в Остине Санджай Дж. Патель, Университет Иллинойса в Урбане / Шампейн
источник
По моему скромному мнению, это не очень помогает.
Раньше я хорошо знал сборку x86. Это немного помогло, когда на моих курсах появилась сборка, однажды она возникла во время собеседования и помогла мне доказать, что компилятор (Metrowerks) генерирует плохой код. Поразительно, как на самом деле работает компьютер, и я чувствую себя интеллектуально богаче, изучив его. В то время было очень весело играть.
Тем не менее, современные компиляторы лучше генерируют ассемблер, чем почти любой пользователь практически любого кода. Если вы не пишете компилятор или не проверяете, что ваш компилятор делает правильные вещи, вы, вероятно, тратите свое время на его изучение.
Я признаю, что многие вопросы, которые программисты C ++ до сих пор с пользой задают, основаны на знании ассемблера. Например: я должен использовать переменные стека или кучи? я должен передать по значению или по константной ссылке? Однако почти во всех случаях я считаю, что этот выбор должен быть сделан на основе читабельности кода, а не на экономии вычислительного времени. (Например, используйте переменные стека всякий раз, когда вы хотите ограничить переменную областью действия.)
Мое скромное предложение - сосредоточиться на действительно важных навыках: разработке программного обеспечения, анализе алгоритмов и решении проблем. С опытом разработки больших проектов ваша интуиция улучшится, что повысит вашу ценность гораздо больше, чем знание ассемблера (на мой взгляд).
источник
Вы должны быть знакомы с одним уровнем «глубже» в системе, на которой вы работаете. Пропуск слишком далеко за один раз не плох, но может быть не так полезен, как хотелось бы.
Программист на языке высокого уровня должен изучать язык более низкого уровня (C - отличный вариант). Вам не нужно проходить весь процесс сборки, чтобы иметь представление о том, что происходит под покровом, когда вы говорите компьютеру создать экземпляр объекта, или создать хэш-таблицу или набор - но вы должны быть в состоянии кодировать их.
Для Java-программиста изучение C поможет вам с управлением памятью и передачей аргументов. Написание некоторой обширной библиотеки Java на C поможет понять, когда использовать какую реализацию Set (хотите ли вы хэш? Или дерево?). Работа с char * в многопоточной среде поможет понять, почему String является неизменным.
Переход на следующий уровень ... Программист переменного тока должен иметь некоторое представление о сборке, и типы сборки (часто встречающиеся в магазинах встраиваемых систем), вероятно, будут хорошо понимать вещи на уровне ворот. Те, кто работает с воротами, должны знать некоторую квантовую физику. И эти квантовые физики, ну, они все еще пытаются выяснить, какова будет следующая абстракция.
источник
Так как вы не упомянули C или C ++ в списке языков, которые вы знаете. Я настоятельно рекомендую изучить их хорошо, прежде чем даже думать о сборке. C или C ++ предоставят все основные понятия, которые полностью прозрачны в управляемых языках, и вы поймете большинство понятий, упомянутых на этой странице, с одним из самых важных языков, которые вы могли бы использовать в реальных проектах. Это реальная добавленная стоимость ваших навыков программирования. Пожалуйста, имейте в виду, что сборка используется в очень специфических областях, и она не так полезна, как C или C ++.
Я бы даже сказал, что вам не следует погружаться в сборку, прежде чем понять, как работают неуправляемые языки. Это почти обязательное чтение.
Вы должны изучить ассемблер, если хотите пойти еще дальше вниз. Вы хотите знать, как именно создается каждая конструкция языка. Это информативно, но это совсем другой уровень сложности.
источник
Если вы хорошо знаете язык, у вас должны быть хотя бы базовые знания технологии на уровень ниже абстракции.
Почему? Когда что-то идет не так, знание базовой механики значительно облегчает отладку странных проблем и, естественно, пишет более эффективный код.
Используя Python (/ CPython) в качестве примера, если вы начинаете получать странные сбои или низкую производительность, знание того, как отлаживать код C, может быть очень полезным, равно как и знание его метода управления подсчетом обращений. Это также поможет вам узнать, когда / если написать что-то как расширение C, и так далее ...
Чтобы ответить на ваш вопрос в этом случае, знание сборки действительно не поможет опытному разработчику Python (слишком много шагов в абстракции - все, что сделано в Python, приведет ко многим инструкциям по сборке)
... но если у вас есть опыт работы с C, то знание "следующего уровня вниз" (сборки) действительно было бы полезно.
Точно так же, если вы используете CoffeScript, то (очень) полезно знать Javascript. Если вы используете Clojure, знание Java / JVM полезно.
Эта идея также работает за пределами языков программирования - если вы используете Assembly, полезно ознакомиться с тем, как функционирует аппаратное обеспечение. Если вы веб-дизайнер, неплохо бы узнать, как реализовано веб-приложение. Если вы автомеханик, неплохо бы иметь некоторые знания по физике
источник
Напишите небольшую программу на c и разберите вывод. Вот и все. Тем не менее, будьте готовы к большей или меньшей степени «служебного» кода, который добавляется в интересах операционной системы.
Сборка помогает понять, что происходит под капотом, потому что она имеет дело непосредственно с памятью, регистрами процессора и тому подобным.
Если вы действительно хотите работать без проблем, не усложняя операционную систему, попробуйте программировать Arduino на ассемблере.
источник
Нет однозначного ответа, так как программисты не все типа. Вам нужно знать, что скрывается под? Если так, то изучите это. Вы просто хотите узнать это из любопытства? Если так, то изучите это. Если это не принесет вам практической пользы, тогда зачем? Нужен ли уровень знаний механика только для управления автомобилем? Нужен ли механику уровень знаний инженера, чтобы работать на автомобиле? Это серьезная аналогия. Механик может быть очень хорошим, продуктивным механиком, не углубляясь в понимание глубины машин, которые он обслуживает. То же самое для музыки. Неужели вы действительно хотите понять сложности мелодии, гармонии и ритма, чтобы быть хорошим певцом или игроком? Нет. Некоторые исключительно талантливые музыканты не умеют читать ноты, не говоря уже о том, чтобы сказать вам разницу между режимами Дориана и Лидии. Если вы хотите, хорошо, но нет, вам не нужно. Если вы веб-разработчик, сборка не имеет практического применения, о котором я могу думать. Если вы находитесь во встроенных системах или что-то действительно специальное, то это может быть необходимо, но если бы это было так, вы бы это знали.
Вот что говорит Джоэл о значении использования языка не высокого уровня: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
источник
На самом деле, что, вероятно, было бы лучше для вас, это класс, который (насколько мне известно) нигде не существует: это был бы класс, который сочетает в себе краткий обзор концепций машинного / ассемблерного языка и адресации хранения с обзором конструкции компилятора , генерация кода и среды выполнения.
Проблема в том, что с высокоуровневым языком аппаратного обеспечения, таким как C # или Python, вы на самом деле не цените тот факт, что каждое ваше движение превращается в сотни, если не тысячи машинных инструкций, и вы не Я не понимаю, как несколько строк языка высокого уровня могут вызвать доступ к огромным объемам памяти и их изменение. Это не так много, что вам нужно точно знать, что происходит «под покровом», но вам необходимо иметь представление о масштабах происходящего и общей концепции типов происходящих вещей.
источник
Мой ответ на этот вопрос появился сравнительно недавно. Существующие ответы охватывают то, что я сказал бы в прошлом. На самом деле, это все еще отражено в главном ответе - «оцените конструкции в программировании более высокого уровня», но это особый случай, который, я думаю, стоит упомянуть ...
Согласно этому сообщению в блоге Джеффа Этвуда , в котором содержится ссылка на исследование, понимание назначения является ключевым вопросом в понимании программирования. Ученики-программисты либо понимают, что нотация просто представляет шаги, которым следит компьютер, и объясняет их шагами, либо постоянно путается, вводя в заблуждение аналогии с математическими уравнениями и т. Д.
Ну, если вы понимаете следующее от ассемблера 6502 ...
Это действительно только шаги. Затем, когда вы научитесь переводить это в оператор присваивания ...
Вам не нужна вводящая в заблуждение аналогия с математическим уравнением - у вас уже есть правильная ментальная модель для сопоставления с ней.
РЕДАКТИРОВАТЬ - конечно, если объяснение, которое вы получаете, в
LDA variable
основномACCUMULATOR = variable
, именно то, что вы получаете из некоторых учебных пособий и ссылок, вы в конечном итоге возвращаетесь к тому, с чего начинали, и это совсем не помогает.Я выучил ассемблер 6502 как мой второй язык, первым из которых был Commodore Basic, и я не очень многому научился в то время - отчасти потому, что было очень мало, но и потому, что ассемблер казался тогда гораздо более интересным , Отчасти время, отчасти потому, что мне было 14 лет.
Я не рекомендую делать то, что я делал, но мне интересно, может быть стоит изучить несколько очень простых примеров на очень простом языке ассемблера, чтобы подготовиться к изучению языков более высокого уровня.
источник
Если вы не писатель компилятора или вам не нужно что-то очень оптимизированное (например, алгоритм обработки данных), изучение кодирования ассемблера не даст вам никаких преимуществ.
Написание и сопровождение кода, написанного на ассемблере, очень сложно, поэтому, даже если вы очень хорошо знаете язык ассемблера, вы не должны его использовать, если нет других способов.
В статье « Оптимизация для SSE: пример из практики » показано, что можно сделать, если вы отправитесь на сборку. Автору удалось оптимизировать алгоритм от 100 циклов / вектор до 17 циклов / вектор.
источник
Запись на ассемблере не даст вам волшебного увеличения скорости, так как из-за количества деталей (распределение регистров и т. Д.) Вы, вероятно, напишете самый тривиальный алгоритм за всю историю.
Кроме того, с современными (читай - спроектированными после 70-80-х годов) сборка процессоров не даст вам достаточного количества деталей, чтобы знать, что происходит (то есть - на большинстве процессоров). Современные PU (процессоры и графические процессоры) довольно сложны в отношении инструкций по планированию. Знание основ сборки (или псевдосборки) позволит понять книги / курсы по компьютерной архитектуре, которые дадут дополнительные знания (кеширование, выполнение вне очереди, MMU и т. Д.). Обычно вам не нужно знать сложные ISA, чтобы понять их (MIPS 5 довольно популярен в IIRC).
Зачем понимать процессор? Это может дать вам гораздо больше понимания того, что происходит. Допустим, вы пишете матричное умножение наивным способом:
Это может быть «достаточно хорошо» для вашей цели (если это матрица 4x4, она может быть скомпилирована в векторные инструкции в любом случае). Однако при компиляции массивных массивов существуют довольно важные программы - как их оптимизировать? Если вы пишете код на ассемблере, вы можете получить несколько% улучшений (если вы не сделаете так, как делает большинство людей - также наивно, недоиспользуя регистры, постоянно загружая / сохраняя в памяти и фактически имея более медленную программу, чем на языке HL) ,
Однако вы можете повернуть вспять линии и волшебным образом повысить производительность (почему? Я оставляю это как «домашнее задание») - IIRC, в зависимости от различных факторов для больших матриц, может быть даже в 10 раз.
Тем не менее, есть работающие над тем, чтобы компиляторы могли это делать ( графит для gcc и Полли для всего, что использует LLVM). Они даже способны преобразовать его в (извините - я пишу блокировку по памяти):
Подводя итог: знание основ сборки позволяет вам копаться в различных «деталях» проектирования процессора, которые позволят вам писать более быстрые программы. Было бы полезно узнать о различиях между архитектурами RISC / CISC или VLIW / vector Процессор / SIMD / .... Однако я бы не стал начинать с x86, поскольку они, как правило, довольно сложные (возможно, и ARM) - для начала достаточно знать, что такое регистр и т. Д.
источник
Обычно это ОЧЕНЬ важно для целей отладки. Что вы делаете, когда система прерывается в середине инструкции и ошибка не имеет смысла? Это гораздо меньше проблем с языками .NET, если вы используете только безопасный код - система почти всегда защитит вас от того, что происходит внутри.
источник
Короче говоря, я думаю, что ответ заключается в том, что вы можете сделать больше, если вы изучите сборку. Изучение ассемблера предоставляет доступ к областям программирования встроенных устройств, проникновения и обхода безопасности, реверс-инжиниринга и системного программирования, в которых очень трудно работать, если вы не знаете ассемблера.
Что касается обучения для повышения производительности программы, это сомнительно в прикладном программировании. Большую часть времени прежде всего нужно уделить так много внимания прежде, чем достичь такого уровня оптимизации, как, например, оптимизация доступа ввода-вывода как на диске, так и в сети, оптимизация построения графического интерфейса пользователя, выбор правильных алгоритмов, максимизация всех ваших ядер. Работая на лучшем оборудовании, которое можно купить за деньги, и переключаясь с интерпретируемых на скомпилированные языки. Если вы не создаете программное обеспечение для других конечных пользователей, аппаратное обеспечение является дешевым по сравнению с почасовой оплатой труда программиста, особенно с доступностью облака.
Кроме того, вам нужно взвесить увеличенную скорость выполнения программы и читабельность вашего кода после того, как вы попали в шину, выйдите или вернетесь в базу кода, чтобы изменить ее через год после написания последней версии.
источник
Я бы порекомендовал алгоритмы обучения: сортировка, связанные списки, двоичные деревья, хеширование и т. Д.
Также изучите lisp, см. «Структура и интерпретация компьютерных программ» groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures. Этот видеокурс научит вас всему, что вам нужно знать, включая алгоритмы (как сделать все на основе несколько примитивных команд, один примитив lisp и несколько провокационных ассемблеров).
Наконец, если вы должны научиться ассемблеру, изучите легкий, такой как ARM (также он используется примерно в 4 раза больше устройств, чем x86).
источник
Ответ таков: просто потому, что используемый вами язык должен быть интерпретирован или скомпилирован в ассемблер в конце. Неважно, язык или машина.
Дизайн языков происходит от того, как работает процессор. Больше на программах низкого уровня, меньше на программах высокого уровня.
В заключение я скажу, что вам нужно знать не только маленький ассемблер, но и архитектуру процессора, которую вы изучаете, изучая ассемблер.
Некоторые примеры: Есть много Java-программистов, которые не понимают, почему это не работает, и даже меньше, чем знают, что происходит при запуске.
Если бы вы знали немного ассемблера, вы бы всегда знали, что содержимое ячейки памяти отличается от числа в переменной указателя, которая «указывает» на эту ячейку.
Хуже того, даже в опубликованных книгах вы будете читать что-то вроде того, как в JAVA примитивы передаются по значению, а объекты по ссылке, что совершенно неверно. Все аргументы в Java передаются по значению, и Java не может передавать объекты в функции, только указатели, которые передаются по значению.
Если вы теперь понимаете, ассемблер, что происходит, то если это не так сложно объяснить, что большинство авторов просто дают вам правдивую ложь.
Конечно, их последствия невелики, но в дальнейшем могут привести к серьезным проблемам. Если вы знаете ассемблер, это не проблема, если нет, то вас ждет долгая и долгая ночь отладки.
источник
String a = "X"; String b = "X"; if( a==b) return true;
что делает на самом деле== true
из-за того, что называется,String interning
что делает компилятор. Все остальные операторы Java также неверны. У Java нет указателей, есть ссылки, которые не одно и то же. И ничто из этого не имеет никакого отношения к ассемблеру. Java передает примитивы по значению, а также ссылки по значению. У Java нет указателей, поэтому она не может их пропустить. Опять все не имеет отношения к знанию ASM.