When first programming PIC processors of the 12C family, I found that the number of RAM locations ("registers") was very restricted. After experimenting with ways of dealing with this, I adopted the following practice. Each register was given a unique name, and then the code was written with each location where a number had to be stored, assigned a meaningful label. Then the task of mapping the memory labels to the register names was performed. In the first instance, I printed out a listing, and on this, marked the first occurance and the last use of each variable label. As soon as the last use point had been reached, then obviously the register was available for the next new label encountered. I wrote a BASIC program that would add columns to the right of the listing, one for each register. The allocation of registers to variables in the code was indicated, as it was assigned, with coloured pencils.
It was found that a little algorithm "tweaking" enabled some variables to be first used later, and finished with sooner.
A scheme was mapped out to automate the assignment of the registers. The idea was to define "metacommands" that would appear in the comment field so as to not interfere with the assembler, but would be identified by a purpose written pre-processor which would which registers were free for use each time a new variable label is encountered. Rules for the structure of such a pre-processor have been formulated, but the pre-processor has not been written.
A mate of mine (MJB) tells me that recent c compilers for small processors handle small RAM very effectively. If I understand him correctly, what he says they do is much the same as I did and reported here. Thus this matter is not a weapon in any "c vs. assembler" battle. It was never meant to be.