Почему программы не пишутся на ассемблере чаще? [закрыто]


216

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

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

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

Если переносимость не является проблемой, то на самом деле, что C будет иметь по сравнению с хорошим ассемблером, таким как NASM?

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


71
Напишите ? Как насчет чтения кода? Вы (и другие) будете читать код намного больше, чем пишете
nos

81
Почему я должен изучать новый язык только потому, что моя программа будет работать на новой платформе? Почему я должен конструировать свои программы так, чтобы они соответствовали представлениям процессоров о том, сколько регистров существует и что вы можете с этим делать? Я стараюсь решать проблемы, а не делать ставки на компьютеры.
Иоахим Зауэр

8
Резюме EDIT: можно использовать компилятор Си.
Майнерсбур

4
@Simon Может быть, тогда у меня были неправильные годы, но я удивлен, что мы обсуждаем ASM против «языка высокого уровня, такого как C» в 2010 году. В частности, та часть, где C является примером языка высокого уровня
matt b

11
@changelog: это не то, как вы пишете по адресу программирования.reddit.com.
BoltClock

Ответы:


331

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

Кроме того, разработчиков ASM намного меньше, чем для других более популярных языков, таких как C.

Кроме того, если вы используете язык более высокого уровня и новые инструкции ASM становятся доступными (например, SSE), вам просто нужно обновить компилятор, и ваш старый код может легко использовать новые инструкции.

Что если следующий процессор имеет в два раза больше регистров?

Обратный ответ на этот вопрос будет следующим: какую функциональность предоставляют компиляторы?

Я сомневаюсь, что вы можете / хотите / должны оптимизировать ASM лучше, чем gcc -O3можете.


10
gcc не так хорош в оптимизации, намного лучше, чем средний человек, но есть много мест, где оптимизаторы не справляются с работой. Согласитесь с вами, хотя в противном случае.
old_timer

4
@dwelch В очень редких случаях gcc (или многие другие компиляторы) не могут должным образом оптимизировать скомпилированный C. Однако в этих случаях вы всегда можете написать ограниченное количество процедур в ASM и связать только эти методы во время сборки.
Cortijon

@Ben S: я изначально редактировал "много", а не "много", потому что "много" используется только для отдельных объектов. Поскольку объектом «много» является множественное число (разработчики), «много» является правильным вариантом. Но я не буду редактировать ваш ответ снова, если вы хотите "много".
Билли ONEAL

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

1
В своей повседневной работе я собираю наш продукт с помощью gcc -g -O0, потому что возможность присоединять к нему gdb в работающей системе и не сходить с ума из-за переменных, оптимизированных вне существования, стоит намного больше для компании, чем было бы оставить еще 4 миллиарда циклов ЦП каждый день (из 3 триллионов). Хруст целых чисел не является узким местом очень часто.
Бернд Джендриссек

1930

Черт, я компилятор.

Я только что отсканировал тысячи строк кода, пока вы читали это предложение. Я просмотрел миллионы возможностей оптимизации вашей единственной линии, используя сотни различных методов оптимизации, основанных на огромном количестве научных исследований, на которые вы потратили бы годы. Я не почувствую никакого смущения, даже небольшого удара, когда я преобразую цикл из трех строк в тысячи инструкций, просто чтобы сделать это быстрее. Мне не стыдно идти на оптимизацию или делать самые грязные трюки. И если вы не хотите, чтобы я, возможно, в течение дня или двух, я буду вести себя так, как вам нравится. Я могу трансформировать используемые мной методы в любое время, даже не меняя ни одной строки вашего кода. Я даже могу показать вам, как ваш код будет выглядеть в сборке, на разных архитектурах процессоров и разных операционных системах и в разных соглашениях о сборке, если хотите. Да, все в считанные секунды. Потому что, вы знаете, я могу; и вы знаете, вы не можете.

PS Кстати, вы не использовали половину написанного вами кода. Я сделал тебе одолжение и выбросил.


99

Я написал сборку ассемблера для чипов 6502, Z80, 6809 и 8086. Я прекратил это делать, как только компиляторы C стали доступны для платформ, на которые я обращался, и сразу стали как минимум в 10 раз более производительными. Большинство хороших программистов используют инструменты, которые они используют по разумным причинам.


72

Я люблю программирование на ассемблере, но требуется больше кода, чтобы сделать то же самое, что и в языке высокого уровня, и существует прямая корреляция между строками кода и ошибками. (Это было объяснено десятилетия назад в «Мифическом человеко-месяце» .)

Можно думать о C как о «сборке высокого уровня», но сделайте несколько шагов выше этого, и вы окажетесь в другом мире. В C # вы не думаете дважды о написании этого:

foreach (string s in listOfStrings) { /* do stuff */ }

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

Изменить: я собрал личную библиотеку кода, используемого для общих задач, и макросов для реализации C-подобных структур управления. Но я врезался в стену в 90-х, когда графический интерфейс стал нормой. Слишком много времени было потрачено на вещи, которые были рутиной.

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


Вы уверены, что? Кажется, я помню, как читал в Code Complete, что это не так ...
jcolebrand

1
Я уверен, что есть момент, когда преимущество «меньшего количества линий» побеждено недостатком «преждевременной оптимизации». Но я давно не смотрел на Code Complete ...
egrunin

6
Немного иронично, если использовать «преждевременную оптимизацию» в качестве аргумента для сборки ... (Я, вероятно, неверно истолковываю вас, хотя. Я все еще думаю, что это смешно.)
Бернд Джендриссек,

Вы все еще можете вызывать функцию в ассемблере, поэтому я сомневаюсь, что цикл foreach занимает от десятков до сотен строк. Или чего мне не хватает?
Себастьян Мах

@phresnel: foreachвыполняет гораздо больше работы, чем for- он создает и использует тип-итератор.
egrunin

15

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

Скорость программы

Да, в сборке вы можете вручную настроить свой код, чтобы использовать каждый последний цикл и сделать его настолько быстрым, насколько это возможно физически. Однако у кого есть время? Если вы напишете не совсем глупую C-программу, компилятор действительно поработает для вас. Вероятно, выполняя не менее 95% оптимизаций, которые вы выполняете вручную, вам не нужно беспокоиться об отслеживании какой-либо из них. Здесь определенно есть правило 90/10, где последние 5% оптимизаций в итоге отнимают 95% вашего времени. Так зачем?


4
+1. Написание ассемблерного кода и быстрый ассемблерный код - это две разные вещи. Если вы используете хороший компилятор, вы получаете код быстрого ассемблера бесплатно.
Ники,

вы получаете быстрый код на ассемблере бесплатно, только если вы знаете, как использовать компилятор, большинство не используют оптимизацию, большинство людей компилируют с опциями отладки и в результате получают плохо сделанный медленный ассемблер. да, в 99% случаев вам не следует прикасаться к нему, просто дотроньтесь до ручек компилятора и не настраивайте вывод напрямую.
old_timer

если вы заботитесь об оптимизации, то вы должны делать это с помощью компилятора ... Если вам не нужны оптимизации, но вы все еще используете сборку, то вы просто глупы.
Брайан Постоу

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

13

Если средняя производственная программа имеет, скажем, 100 тыс. Строк кода, а каждая строка содержит около 8-12 инструкций ассемблера, это будет 1 миллион инструкций ассемблера.

Даже если бы вы могли написать все это вручную с приличной скоростью (помните, что это в 8 раз больше кода, который вы должны написать), что произойдет, если вы захотите изменить некоторые функции? Понимание того, что вы написали несколько недель назад из этих 1 миллиона инструкций, - это кошмар! Там нет модулей, нет классов, нет объектно-ориентированного дизайна, нет фреймворков, нет ничего. И количество схожего кода, который вы должны написать даже для самых простых вещей, в лучшем случае устрашает.

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


8

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


8
«Ассамблея латынь».
Адриано Вароли Пьяцца

4
@Adriano: за исключением того, что есть много разных диалектов, и ни один из них не похож на другой.
Иоахим Зауэр

1
Конечно, но я имел в виду, что изучение программирования на любом из них дает вам представление об архитектуре машины, которая помогает вам на более высоких уровнях. Если вы не имеете дело с постраничной памятью, в этом случае вы в конечном итоге шрамы. Как читать Кармен 16 от Катулла.
Адриано Вароли Пьяцца

5
@ Adriano "Сборка - это латынь", ни один асм не хрюкает. Один ворчание для камня 2 грунта для оленя, 3 грунта для огня - хорошо для простых вещей, но трудно управлять империей.
Мартин Беккет

1
@Martin: Вы когда-нибудь пытались сделать сложную арифметику с римскими цифрами?
Адриано Вароли Пьяцца

6

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

Однако, что касается написания большого количества кода на ассемблере, есть несколько причин, по которым это не так много сделано.

  • Там просто нет (почти) необходимости. За исключением чего-то вроде очень ранней инициализации системы и, возможно, нескольких фрагментов ассемблера, скрытых в функциях C или макросах, весь очень низкоуровневый код, который когда-то мог быть написан на ассемблере, может быть без труда написан на C или C ++.

  • Код на языках более высокого уровня (даже C и C ++) сжимает функциональность в гораздо меньшее количество строк, и есть значительные исследования, показывающие, что количество ошибок коррелирует с количеством строк исходного кода. То есть та же проблема, решаемая в ассемблере и C, будет иметь больше ошибок в ассемблере просто потому, что она длиннее. Тот же аргумент мотивирует переход на языки более высокого уровня, такие как Perl, Python и т. Д.

  • При написании на ассемблере вам приходится иметь дело с каждым аспектом проблемы, начиная с детальной компоновки памяти, выбора инструкций, выбора алгоритмов, управления стеками и т. Д. Языки более высокого уровня отнимают все это у вас, поэтому они настолько плотнее в условия LOC.

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


6

Как разработчик, который проводит большую часть своего времени в мире встроенного программирования, я бы сказал, что сборка далека от мертвого / устаревшего языка. Существует определенный уровень кодирования, близкий к металлическому (например, в драйверах), который иногда нельзя выразить так же точно или эффективно на языке более высокого уровня. Мы пишем почти все наши процедуры аппаратного интерфейса на ассемблере.

При этом этот ассемблерный код упакован так, что его можно вызывать из кода C, и он обрабатывается как библиотека. Мы не пишем всю программу в сборке по многим причинам. Прежде всего это мобильность; наша кодовая база используется в нескольких продуктах, использующих разные архитектуры, и мы хотим максимизировать объем кода, который может быть разделен между ними. Во-вторых, знакомство с разработчиком. Проще говоря, школы не преподают сборку, как раньше, и наши разработчики гораздо более продуктивны в Си, чем в сборке. Кроме того, у нас есть широкий выбор «дополнений» (таких как библиотеки, отладчики, инструменты статического анализа и т. Д.), Доступных для нашего кода C, которые недоступны для кода на ассемблере. Даже если бы мы хотели написать программу с чистой сборкой, мы не сможем, потому что несколько критически важных аппаратных библиотек доступны только как C libs. В каком-то смысле это проблема курицы / яйца. Люди отстранены от сборки, потому что для нее не так много библиотек и инструментов разработки / отладки, но библиотеки / инструменты не существуют, потому что недостаточно людей используют сборку, чтобы оправдать усилия по их созданию.

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


6

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

Итак, что вы в основном говорите, что при умелом использовании сложного ассемблера вы можете сделать свой код ASM все ближе и ближе к C (или в любом случае другому языку низкого уровня своего собственного изобретения), пока в конечном итоге вы не станете просто так же продуктивно, как программист на Си.

Это отвечает на ваш вопрос? ;-)

Я не говорю это праздно: я программировал, используя именно такой ассемблер и систему. Более того, ассемблер может быть нацелен на виртуальный процессор, а отдельный транслятор скомпилирует выходные данные ассемблера для целевой платформы. Как и в случае с IF от LLVM, но в ранних формах, предшествующих ему примерно на 10 лет. Так что была мобильность, плюс возможность писать подпрограммы для конкретного целевого ассемблера, где это необходимо для эффективности.

Писать с использованием этого ассемблера было примерно так же продуктивно, как C, и по сравнению с GCC-3 (который был примерно к тому времени, когда я принимал участие) ассемблер / переводчик создавал код, который был примерно таким же быстрым и обычно меньше. Размер был действительно важен, и у компании было мало программистов, и они были готовы научить новых сотрудников новому языку, прежде чем они смогут сделать что-нибудь полезное. И у нас была резервная копия, что люди, которые не знали ассемблера (например, клиенты), могли написать C и скомпилировать его для того же виртуального процессора, используя то же соглашение о вызовах и так далее, чтобы он аккуратно взаимодействовал. Так что это было похоже на незначительную победу.

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

В итоге: вам может не понравиться C, но это не значит, что усилия по использованию C больше, чем усилия по созданию чего-то лучшего.


5

Сборка не переносима между разными микропроцессорами.


Это не совсем верно с современными процессорами и программами на ассемблере, вы можете ориентироваться на разные процессоры так же, как в C. Конечно, вы не сможете использовать полный набор инструкций в этом случае, но и вы, если вы его напишите, тоже не будете в C. Переносимость не является главной задачей.
Блинди

6
Может быть, вы имеете в виду архитектуру .
Бен С

2
@Blindy - Вы можете использовать разные процессоры семейства x86, но в инструкциях по сборке определенно нет общего между вариантом x86 и процессором ARM, Z80 или 8051.
semaj

Правда, но тогда вы не можете запрограммировать z80 на c. Я думаю, что мы все говорим о нормальных процессорах x86 / x64 здесь.
Блинди

1
Весь мир не x86. Ничто в «разных микропроцессорах» не предполагает, что все они выполняют один и тот же набор команд.
Бернд Джендриссек

5

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

Технология приходит и делает вещи проще и доступнее.

РЕДАКТИРОВАТЬ - чтобы прекратить обидеть людей, я удалил определенные слова.


4
Вы все еще оскорбляете луддитов словомTechnology
SeanJA,

1
«Мы» не говорим по-латыни?
сыро

Ни латынь, ни арамейский не исчезли, потому что они были заменены более совершенной технологией (то есть более легким для изучения / выбора языка). На самом деле, латынь все еще с нами в Европе. Все римские языки основаны на латыни. На современном (нео) арамейском сегодня говорят почти полмиллиона человек. Причины, по которым эти языки больше не распространены, являются историческими (точнее, геополитическими), а не технологическими. По той же причине английский язык является языком общения науки и правящих классов нашего времени - люди последней империи, англичане (а теперь и американцы), говорят на нем.
Ritz

4

Зачем? Просто.

Сравните это:

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

с участием

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

Они идентичны по характеристикам. Второй - даже не ассемблер, а .NET IL (промежуточный язык, похожий на байт-код Java). Вторая компиляция преобразует IL в нативный код (т.е. почти на ассемблере), что делает его еще более критичным.


3

Я предполагаю, что ASM даже на x86 (_64) имеет смысл в тех случаях, когда вы получаете много, используя инструкции, которые сложно оптимизировать для компилятора. Например, x264 использует много ассемблера для кодирования, и прирост скорости огромен.


2

Я уверен, что есть много причин, но я могу подумать о двух

  1. Код на ассемблере определенно труднее читать (я уверен, что его написание требует больше времени)
  2. Когда над продуктом работает огромная команда разработчиков, полезно разделить код на логические блоки и защитить его интерфейсами.

1
Обратите внимание, что вы также можете разделить сборку на логические блоки.
Пол Уильямс

2

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

Поэтому самым быстрым способом повышения производительности было бы использование языков, в которых одна отдельная строка кода выполняла больше, и это действительно работает, по крайней мере, для таких сложных языков, как FORTRAN и COBOL, или для предоставления более современного примера C.


2

Переносимость - это всегда проблема, если не сейчас, то хотя бы в конце концов. Индустрия программирования тратит миллиарды каждый год на портирование старого программного обеспечения, которое на момент его написания «явно» не имело проблемы переносимости.


2
«Не нужно будет переносить его на другую архитектуру», звучит для меня очень похоже на «Не нужно больше двух цифр в году».
Дэвид Торнли

Или мы не можем использовать C #, потому что Windows может не появиться в следующем году?
Мартин Беккет

Например, компьютеры Apple MacIntosh, основанные на процессорах серии Motorola MC68000, PowerPC (IBM et all), а теперь и процессоры Intel x86 (IA-32 (e)). Так что да, переносимость является проблемой для любой системы, используемой достаточно долго, и любой программист, который не укусил своим кодом, работающим дольше, чем ожидалось, еще не испытал этого.
mctylr

@Martin: Через двадцать лет будет много C # -программ, которые люди хотят запускать, и поэтому будет возможность компилировать и запускать C # -программы. В C # нет ничего определенного, хотя через двадцать лет я был бы удивлен, если бы он все еще был таким же популярным, как сейчас. Однако через двадцать лет наши процессоры будут существенно отличаться. Программа на ассемблере, написанная в 1990 году, вполне может быть запущена в наши дни, но она точно не будет оптимальной и будет работать медленнее, чем скомпилированная C.
Дэвид Торнли

Это то, что я имел в виду - у меня гораздо больше проблем с портированием, потому что высокоуровневая инфраструктура изменилась с 6 месяцев назад, чем я, потому что изменились инструкции в x86 - особенно потому, что asm, написанный вручную, имеет тенденцию придерживаться самых простых методов.
Мартин Беккет

2

Был замкнутый цикл, поскольку сборка стала менее распространенной: по мере развития языков более высокого уровня наборы инструкций на ассемблере создавались меньше для удобства программиста и больше для удобства компиляторов.

Поэтому сейчас, на самом деле, может быть очень трудно принять правильные решения, скажем, о том, какие регистры следует использовать или какие инструкции немного более эффективны. Компиляторы могут использовать эвристику, чтобы выяснить, какие компромиссы, вероятно, принесут наилучшие результаты. Мы можем, вероятно, продумать небольшие проблемы и найти локальные оптимизации, которые могут превзойти наши, теперь достаточно сложные, компиляторы, но есть вероятность, что в среднем случае хороший компилятор с первой попытки справится лучше, чем, вероятно, хороший программист. В конце концов, как и Джон Генри, мы могли бы побить машину, но мы могли бы серьезно сгореть, добравшись туда.

Наши проблемы сейчас тоже совсем другие. В 1986 году я пытался выяснить, как немного увеличить скорость работы с небольшими программами, которые включали вывод на экран нескольких сотен пикселей; Я хотел, чтобы анимация была менее резкой. Справедливый случай для ассемблера. Сейчас я пытаюсь понять, как представить абстракции вокруг языка контрактов и политики обслуживания для ипотеки, и я бы предпочел прочитать что-то похожее на язык, на котором говорят деловые люди. В отличие от макросов LISP, макросы ассемблера не навязывают много правил, поэтому даже если вы сможете получить что-то достаточно близкое к DSL в хорошем ассемблере, он будет подвержен всевозможным изворотам, которые выиграли ' Это не вызывает у меня проблем, если я написал один и тот же код на Ruby, Boo, Lisp, C # или даже F #.

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


2

То же самое, что сказали другие.

В старые добрые времена до изобретения C, когда единственными языками высокого уровня были такие вещи, как COBOL и FORTRAN, было много вещей, которые просто невозможно было сделать без обращения к ассемблеру. Это был единственный способ получить полную гибкость, иметь возможность доступа ко всем устройствам и т. Д. Но затем был изобретен C, и почти все, что было возможно в сборке, было возможно в C. Я написал очень мало сборок с тех пор затем.

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


Да, на месте Несколько лет назад Fortran Disk и Tape I / O на мэйнфреймах IBM были практически бесполезны, поэтому мы написали наши собственные процедуры ввода-вывода в 370 / Assembler и вызвали их из кода Fortan IV. И написание ассемблера помогло мне понять основную архитектуру. Я не писал никакого ассемблера уже несколько лет, и все молодые люди, с которыми я работаю, никогда не писали - но я бы хотел, чтобы это было так познавательно.
Саймон Найтс

2

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

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

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

Лично я думаю, что рынок сильно поддерживает языки высокого уровня. Если бы ассемблер был единственным языком, существующим сегодня, тогда на программировании было бы на 70% меньше людей, и кто знает, где будет наш мир, вероятно, еще в 90-х годах. Языки более высокого уровня привлекают более широкий круг людей. Это позволяет большему количеству программистов создавать необходимую инфраструктуру нашего мира. Развивающиеся страны, такие как Китай и Индия, получают большую пользу от таких языков, как Java. Эти страны будут быстро развивать свою ИТ-инфраструктуру, и люди станут более взаимосвязанными. Поэтому я хочу сказать, что языки высокого уровня популярны не потому, что они генерируют превосходный код, а потому, что они помогают удовлетворить спрос на мировых рынках.


+1 за вещь черного ящика. Да, мы используем черные ящики, и нет возможности заглянуть в них (слишком просто). Как C # foreach действительно работает? Кто знает. Microsoft сказала, что это прекрасно. Тогда это должно быть.
ern0

Кроме того, не забывайте, что с «языком высокого уровня» приходит много других вещей, которые имеют значение в реальном мире. C поставляется со стандартными библиотеками (математика, обработка строк, ввод-вывод и т. Д.), А затем тяжелые веса, такие как Java, поставляются с множеством других пакетов и библиотек для подключения, обработки изображений, обработки данных, веб-разработки и т. Д. Это вопрос использование вашего времени, чтобы сосредоточиться на получении 1 детализированной задачи с высокой производительностью на одной платформе (таким образом, используя сборку), вместо того, чтобы тратить одно и то же время на выполнение гораздо более масштабной задачи на нескольких платформах с минимальными ошибками
JBX

1

Я сейчас изучаю ассемблер в comp org, и, хотя это интересно, писать тоже очень неэффективно. Нужно держать в голове больше деталей, чтобы все заработало, и писать медленнее одинаково , Например, простая 6-строчная строка цикла в C ++ может равняться 18 или более строкам сборки.

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


1

То, что C имеет по сравнению с хорошим макро-ассемблером, это язык C. Проверка типов. Петлевые конструкции. Автоматическое управление стека. (Почти) автоматическое управление переменными. Методы динамической памяти на ассемблере - огромная боль в заднице. Правильное выполнение связанного списка просто страшно вниз по сравнению с C или, что еще лучше, списком foo.insert (). И отладка - ну, нет конкурса на то, что легче отлаживать. HLLs выигрывают руки там.

Я написал почти половину своей карьеры ассемблера, что позволяет мне легко думать в ассемблере. это помогает мне увидеть, что делает компилятор C, что снова помогает мне писать код, который компилятор C может эффективно обрабатывать. Хорошо продуманная подпрограмма, написанная на C, может быть написана для вывода именно того, что вы хотите, на ассемблере с небольшой работой - и она переносима! Мне уже пришлось переписывать несколько старых процедур asm обратно на C по кроссплатформенным причинам, и это не интересно.

Нет, я буду придерживаться C и буду иметь дело с небольшим замедлением производительности по сравнению с производительностью, которую я получаю с помощью HLL.


1

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

Тем не менее, я думаю, что есть все еще действительные применения для сборки. Например, у меня есть несколько довольно оптимизированных процедур сборки для обработки больших объемов данных, использования SIMD и следования параноидальному подходу «каждый бит священен» [quote V.Stob]. (Но учтите, что наивные сборки часто намного хуже, чем то, что компилятор сгенерировал бы для вас.)


1

C - макроассемблер! И это самый лучший!

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

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


1

Люди, кажется, забывают, что есть и другое направление.

Почему вы пишете в Ассемблере в первую очередь? Почему бы не написать программу на действительно низкоуровневом языке?

Вместо того

mov eax, 0x123
add eax, 0x456
push eax
call printInt

Вы могли бы так же хорошо написать

B823010000
0556040000
50 
FF15.....

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

И причина, по которой вы до сих пор предпочитаете Ассемблер, - это причина, по которой другие люди предпочитают C ...


0

Потому что так всегда: время проходит, и хорошие вещи уходят тоже :(

Но когда вы пишете код asm, это совершенно другое чувство, чем когда вы кодируете высокоуровневые языки, хотя вы знаете, что это гораздо менее продуктивно. Вы как художник: вы можете рисовать все, что вам нравится, как вам угодно, без каких-либо ограничений (ну, только с помощью функций процессора) ... Вот почему я люблю это. Жаль, что этот язык уходит. Но пока кто-то все еще помнит это и кодирует, он никогда не умрет!


Правда. С другой стороны, вы испытываете унижение, когда кассир и супермаркет отказываются обналичивать ваш чек, презрительно говоря: «О, вы программируете на языке низкого уровня».
Джей

0

$$$

Компания нанимает разработчика, который поможет превратить код в $$$. Чем быстрее это полезно будет создан код, тем быстрее компания сможет превратить этот код в $$$.

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


0

Преимущество HLL еще больше, когда вы сравниваете сборку с языком более высокого уровня, чем C, например, Java, Python или Ruby. Например, в этих языках есть сборка мусора: не нужно беспокоиться о том, когда освобождать кусок памяти, и нет утечек памяти или ошибок из-за слишком раннего освобождения.


0

Как уже упоминалось ранее, причина существования любого инструмента заключается в том, насколько эффективно он может работать. Поскольку HLL могут выполнять те же задачи, что и многие строки кода asm, я полагаю, что ассемблер естественным образом заменяется другими языками. А что касается аппаратной обработки - встроенная сборка в C и других вариантах зависит от языка. Доктор Пол Картер говорит на языке ассемблера ПК

«... лучшее понимание того, как на самом деле работают компьютеры на более низком уровне, чем в таких языках программирования, как Pascal. Получив более глубокое понимание того, как работают компьютеры, читатель может быть гораздо более продуктивным при разработке программного обеспечения на языках более высокого уровня, таких как C и C ++. Обучение программированию на ассемблере является отличным способом достижения этой цели ».

У нас есть введение в сборку на курсах моего колледжа. Это поможет прояснить понятия. Однако я сомневаюсь, что кто-либо из нас написал бы 90% кода в сборке. Насколько актуальны сегодня глубокие знания в области сборки?


-2

Просматривая эти ответы, я бы поспорил, что 9/10 респондентов никогда не работали со сборкой.

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


1
+1 упоминание людей без какого-либо опыта asm, и еще один +1 для "кодирования в C, как asm". Когда я пишу приложения для C ++ (да, CPP, а не C) для встраиваемых приложений, я пишу как asm, например, вообще не использую new / malloc ().
ern0

Итак, вы используете много вещей, таких как char buf [MAX_PATH], который затем падает, когда у кого-то есть данные размера MAX_PATH + n? ;)
Пол

1
@paulm - Ты имеешь в виду, как С?
Роб

1
Я надеюсь, что авторы ассемблера не избегают использования malloc (). Да, на встроенных вы ограничены в памяти. Но сделайте это на Unix или другом настольном компьютере (или даже на большинстве мобильных ОС), и вы просто излишне ограничиваете себя и своих пользователей. Кроме того: чем меньше LOC вы пишете, тем меньше вероятность ошибки, что означает, что код более высокого уровня, вероятно, будет иметь меньше ошибок, чем более низкий.
Uliwitness

1
Просто посмотрел, потому что я был подозрительным и, да, я уверен, что могу сказать, что Redditors и HNers здесь.
Роб
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.