Ho imparato dal libro di Kip Irvine . Se ignori le (giuste) critiche alle sue (irrilevanti) biblioteche, posso consigliarlo come una buona introduzione al linguaggio stesso, anche se per le cose davvero interessanti devi cacciare gli ossessivi in rete.
Penso sia utile capire cosa succede ai livelli inferiori. Durante la ricerca in assembler imparerai a conoscere il pipelining della cpu, la previsione dei rami, l'allineamento della cache, il SIMD, il riordino delle istruzioni e così via. La conoscenza di questi ti aiuterà a scrivere un codice migliore di alto livello.
Inoltre, la saggezza convenzionale è quella di non cercare di ottimizzare manualmente l'assembly la maggior parte del tempo, ma lasciare che il compilatore se ne preoccupi. Quando vedi alcuni esempi delle cose distorte generate dai compilatori, capirai meglio perché vale la saggezza convenzionale.
Esempio: gli LFSR girano velocemente con l'istruzione rotate-with-carry, per casi specifici come questo è altrettanto facile scrivere la versione dell'assembler quanto scoprire se il compilatore è abbastanza intelligente da capirlo. A volte sai qualcosa che il compilatore non sa.
Aumenta anche la comprensione dei problemi di sicurezza: scrittura o esecuzione, overrun dello stack, ecc.
Alcuni problemi di concorrenza diventano evidenti solo quando si è consapevoli di ciò che sta accadendo a livello di istruzione.
A volte può essere utile durante il debug se non si dispone del codice sorgente completo.
C'è il valore della curiosità. Come vengono implementate le funzioni virtuali? Hai mai provato a scrivere programmi DirectX o COM in assembler? Come vengono restituite strutture di grandi dimensioni, la funzione chiamante offre uno spazio per esse o viceversa?
Poi ci sono linguaggi assembly speciali per l'hardware grafico, sebbene i linguaggi shader siano diventati di alto livello alcuni anni fa, tutto ciò che ti permette di pensare a un problema in un modo diverso va bene.