If you pass a list to the first argument of cons then you are making a nested list. First lets say we make your initial list and the symbol x variables:
(defparameter *nils* '(nil nil nil nil))
*nils* ; ==> (nil nil nil nil)
(defparameter *x* 'x)
*x* ; ==> x
So how do we remove the two first. Well we can remove one with (cdr *nils*) so that means we can do it twice:
(cdr (cdr *nils*))
; ==> (nil nil)
Actually more than one car and cdr accessor has a shorthand upto 5 combinations. The shorthand is just starting with c and do the a/d's and end with r like this:
(cddr *nils*)
; ==> (nil nil)
Goodie, how do we add *x* in front of that? Well cons is defines as making an element in front of the second argument, thus (cons *x* (cddr *nils*)) will make(x nil nil). Again if you want to have anotherx` in front of that you do the same with the firt result:
(cons *x* (cons *x* (cddr *nils*)))
; ==> (x x nil nil)
Using list* is like nested cons with a tail in the end. Thus the above code can be replaced with:
(list* *x* *x* (cddr *nils*))
; ==> (x x nil nil)
Now replacing the variables the expression that was stored as their value (substitution method):
(list* 'x 'x (cddr '(nil nil nil nil)))
; ==> (x x nil nil)
(setf (first *NILS*) :hello)=>(:HELLO NIL NIL NIL).