The few times I've done assembly language programming, it's usually been either the C preprocessor or the compiler's inline assembly capabilities.
The most involved of these was actually just written in straight C. I'd compile it, look at the output and then fiddle with the C code until the output was optimal.
(This was not gcc though; it was my employer's embedded compiler, and it let me pin variables to specific machine registers. This let me bypass the register allocator.)