I am no fan of writing the sorts of highly non-portable code that tend to be characteristic of coding applications in assembly language. I rather prefer the idea of using high level languages that abstract away from the "physical" abstractions of registers and memory addressing.
However, there are several very good reasons to write code in assembly language:
If you are writing a compiler for a higher level programming language, there must be some rendering into the native assembly language.
This is true, to some degree, even with the Transmeta Crusoe architecture, as someone needs to write the platform-specific support code.
On embedded platforms, the choice may be between FORTH and assembly language. There are certain constraints involved when programming PICs and other sorts of computers that have minscule amounts of memory resources...
Once a piece of software has been profiled and tuned, there may be some place where it can prove worthwhile to "tune" some routine at the assembly language level.
For instance, in cryptographic software, it is not uncommon for there to be algorithms deployed in tuned assembly language for the "block" crypto algorithm.
There are some perverse hacks that cannot be accomplished any other way!
One of the never-attained "Holy Grails" of computing, the hoped-for "UNiversal Computer Oriented Language," a sort of universal assembly language that should be a good intermediary to allow running any computer language on any kind of computer hardware.
HLA - High Level Assembler
TERSE is a 'macro assembler' system that provides somewhat C -like syntax for many machine language constructs, so that you write TERSE code, which is then expanded into IA-32 assembly language code, ready to be processed using an ordinary assembler.
When you really want a binary executable 45 bytes long...
Transforms NASM assembler into GAS-compatible form and vice-versa.