Aprendí del libro de Kip Irvine . Si ignora las críticas (justas) de sus bibliotecas (irrelevantes), puedo recomendarlo como una buena introducción al lenguaje en sí, aunque para las cosas realmente interesantes debe buscar obsesivos en la red.
Creo que es útil comprender lo que sucede en los niveles inferiores. A medida que investigue sobre ensamblador, aprenderá sobre canalización de CPU, predicción de rama, alineación de caché, SIMD, reordenación de instrucciones, etc. El conocimiento de estos le ayudará a escribir mejor código de alto nivel.
Además, la sabiduría convencional es no intentar optimizar manualmente el ensamblaje la mayor parte del tiempo, sino dejar que el compilador se preocupe por ello. Cuando vea algunos ejemplos de las cosas retorcidas que generan los compiladores, comprenderá mejor por qué se sostiene la sabiduría convencional.
Ejemplo: los LFSR se ejecutan rápido con la instrucción rotate-with-carry, para casos específicos como este es tan fácil escribir la versión del ensamblador como descubrir si el compilador es lo suficientemente inteligente como para resolverlo. A veces simplemente sabes algo que el compilador desconoce.
También aumenta su comprensión de los problemas de seguridad: escritura o ejecución, desbordamientos de pila, etc.
Algunos problemas de concurrencia solo se hacen evidentes cuando se da cuenta de lo que está sucediendo en el nivel por instrucción.
A veces puede ser útil al depurar si no tiene el código fuente completo.
Ahí está el valor de la curiosidad. ¿Cómo se implementan las funciones virtuales de todos modos? ¿Alguna vez ha intentado escribir programas DirectX o COM en ensamblador? ¿Cómo se devuelven las estructuras grandes, la función de llamada ofrece un espacio para ellas o viceversa?
Luego están los lenguajes ensambladores especiales para hardware de gráficos, aunque los lenguajes de sombreado alcanzaron un alto nivel hace unos años, cualquier cosa que te permita pensar en un problema de una manera diferente es bueno.