I've never written any long programs in assembly. But from my superficial experience it appears not as hard as people make it seem like.
The only thing I can't quite wrap my head around is: How does one practically carry out register allocation? While in x86 there is not much space, x64 and RISC designs (AVR, ARM) give you a plenty of registers.
How do assembly programmers choose which variables should stay in the registers, when to transfer them from/to memory and finally, how do they keep track of every variable?