Любой профессиональный подход требует основательности, скрупулёзности и упорства. ЯП тоже является инструментом, который необходимо глубоко знать. И вложение в изучение ЯП, который является куда более универсальным инструментом, чем конкретный ассемблер, намного эффективнее.
Ассемблер содержит кучу информации частного характера, которая за пределами конкретного процессора не пригодится. А тот же С является по сути портабельным макроассемблером, как тут уже сказали. Это очень низкоуровневая концепция, там просто неоткуда взяться большому оверхеду. И если в прежние времена ещё можно было отнести неэффективность на слабость (тупость) компилятора, то с развитием вычтехники стали появляться и оптимизирующие компиляторы (а это уже где-то вторая половина 1990-х), генерирующие код, обойти руками который было очень непросто. Я по молодости соревновался с IAR v1.40 для AVR, сам тогда пришёл от железа и ассемблера, и был сильно удивлён, что "тупая железка" (РС) генерит точно такие же инструкции, как я бы и сам написал. С этого и возник интерес к С (до этого считал его ЯП высокого уровня, куда, дескать, ему там в такие малыши как AT90S2313 и даже AT90S8515).
Настройка опций компилятора делается обычно один раз (потом уже по месту что-то корректируется, если надо) и занимает очень незначительное время по сравнению с написанием кода. А то, что Borland лохматых версий пихал кучу лишнего, не может быть основанием для выводов об ущербности технологии. Кстати, и современные тоже нередко пихают кучу лишнего, просто щас на этого никто не смотрит — ресурсов стало вдосталь (памяти, дискового пространства). И только на ембедде приходится обращать на это сугубое внимание. Да и то далеко не везде (на ембеддед линуксах уже тоже мало кто заморачивается) — преимущественно это осталось в мире МК.
* * *
Соревноваться на уровне ассемблера вы можете достаточно эффективно на простых процессорах — 8/16-битниках типа AVR, MSP430, PIC. Когда перед вами дивайс вроде того же Blackfin, будете удивлены тому, какой код генерит компилятор: глядя на него в первый момент возникает мысль, что это какой-то наркоман писал — инструкции все поперемешаны. Но когда начинаете писать ровный (по-человечески чтобы выглядело) код сами, то прилетают сообщения о простое конвейера, что, де, вот это значение Р-регистра (регистр-указатель) не может быть использовано в следующей инструкции, т.к. оно не доехало до стадии Execute на конвейере, и т.п. и чтобы избежать простоя, перемещаете загрузку указателя раньше в потоке инструкций... И обнаруживаете, что начинаете писать такой же "наркоманский" код, где команды, составляющие связанную группу действий (например, чтение-изменение-запись переменной в памяти), начинают размазываться по коду и перемешиваться с командами из других групп действий.
И тут доходит, что компилятор-то именно это всё и делает. Он "знает" про свойства конвейера процессора и пытается избежать простоев. Т.е. уже на старте компилятор обходит неподготовленного, знающего только ассемблер, человека. Чтобы дорасти до компилятора, тут нужна практика и опыт, который тоже нужно поддерживать. И обойти компилятор тут очень непросто. И даже писать такой перемешанный код тоже весьма утомительно, не говоря уже о его сопровождении.
Это пример про относительно простой процессор, в котором просто длинный конвейер. А если взять современные суперскаляры с внеочередным исполнением инструкций и переименованием регистров, где на аппаратном уровне идёт загрузка нескольких вычислительных юнитов, где продвинутые предсказатели ветвлений и т.п., то прокачать владение ассемблером хотя бы до того уровня, который вложили компиляторописатели в инструмент, потребует просто жить в этом мире. А завтра выйдет процессор с другой, обновлённой микроархитектурой (ARM их плодит как горячие пирожки), и всё по-новой, изучать особенности поведения, экспериментировать, исследовать... Когда процессоров было три штуки на всё, в этом, возможно, и был какой-то смысл. В нынешнее время это просто непозволительное расточение времени и сил. При сомнительном результате.