The irony of implementing Lisp in assembly is that, almost for free (sorry about that), you get precise, convenient control of the memory situation. Just put the gc root exclusively in registers.
I wrote a Lisp interpreter in assembly that dedicates 4-5 registers for the current expression, eval environment, and so on. The mark-sweep collector starts from these registers.