С появлением портативных языков высокого уровня для программистов или университетских учебных программ по компьютерным наукам все чаще пренебрегали обучением машинному коду. Причина этого в том, что машинный код устарел и время можно потратить на что-то другое.
Что касается очень многих людей, которые в конечном итоге будут работать где-нибудь в сфере технологий, я могу с ними согласиться. Тем, кто в конечном итоге займется веб-разработкой, проектированием интерфейсных графических интерфейсов пользователя или теми, чья карьера в основном будет состоять из работы только на высшем уровне языков, возможно, никогда не потребуется применять знания, полученные при работе с машинным кодом. В остальном программисты, которые будут писать код, скажем, на C или C ++, будут работать с языком, который намного ближе к аппаратному обеспечению. Для меня это означает две основные вещи
- Они должны знать, как их код будет напрямую интерпретироваться компилятором.
- Они должны знать, эффективны ли их действия, учитывая все возможные альтернативы.
Так как же написать ассемблерный код достичь этих целей?
Когда человек пишет ассемблерный код, он в основном кодирует на самом низком возможном уровне (за исключением написания кода в двоичном формате). Инкапсулированные детали, включая то, как будет сортироваться массив или чем фактически станет стек вызовов с большим количеством вызовов функций, станут для них очевидными. Используя метафору механики, программист больше не будет водителем, блаженно не осознающим, что скрывается под капотом. Они будут знать назначение двигателя и трансмиссии.
Это важно, потому что, когда программист кодирует на языке высокого уровня, если он не осведомлен об обязанностях компилятора, у него может возникнуть соблазн предположить, что компилятор автоматически поступит правильно. НАПРИМЕР.
- Очистить всю память с помощью сборщика мусора
- Сортировка массивов или подобных структур данных наиболее удобными способами
И это может быть, а может и не быть.
Более того, инструкции, составляющие, скажем, C ++, могут считаться столь же дорогостоящими, независимо от того, что они из себя представляют. НАПРИМЕР. В следующем фрагменте кода на C ++ есть три инструкции.
int x = 1;
cout ‹* x ‹< endl;
x ++;
cout ‹---------------- x ‹< endl;
Объявление переменной x - это первая инструкция, вывод значения x - это вторая инструкция, а увеличение значения x - это третья инструкция. Четвертый - просто дубликат второго.
Можно было бы предположить, что все эти инструкции одинаково дороги с точки зрения времени или памяти, но это не так. Увеличение x - довольно простая операция, поэтому это произойдет быстро. По сравнению с этим вывод переменной x происходит значительно медленнее. Современные компьютеры просто слишком быстры, чтобы пользователь мог различить их с помощью только одного экземпляра этих инструкций. Однако, поместив этот фрагмент в цикл for, скажем, на 100 000 итераций и исключив ввод-вывод, можно заметить значительное преимущество в скорости при выводе печати на консоль.
Это вещи, которые не очевидны на первый взгляд, когда кто-то кодирует только языки высокого уровня, но изучает это с опытом работы с языками ассемблера низкого уровня. Вдобавок к этому, когда кто-то кодирует в Assembly, он узнает больше об архитектуре компьютера, и это также помогает понять логику всех их действий.
Кодирование на ассемблере может быть устаревшим с точки зрения программирования для школы или работы, но я считаю, что оно все еще имеет ценность. Тот, кто хоть немного знает об ассемблере, сможет лучше принять решение о том, какие алгоритмы им нужно написать для определенного сценария.
Вот почему я считаю, что каждый back-end программист должен хотя бы немного изучить Assembly.