One integer variable is enough, because it effectively gives you infinite memory. Three times infinite memory is as much as one times infinite memory. What matters is not the number of integer variables, but which operations you're allowed to do on them. If 3 integer variables i,j,k with operations o1,o2,...,on are enough to encode a stack, then you can do the same with one integer variable x. You just represent i as all the bits in x whose position is 0 mod 3, j as all the bits whose position is 1 mod 3 and k as all the bits whose position is 2 mod 3. Then you just modify operations to only work on those bits that the operation applies to.
For example if you have an operation increment_i, and you start with i=j=k=0 then it works like this:
ijkijkijk...
start: i=0,j=0,k=0 and x = 000000000...
increment_i: now i=1,j=0,k=0 and x = 100000000...
increment_i: now i=2,j=0,k=0 and x = 000100000...
increment_i: now i=3,j=0,k=0 and x = 100100000...
increment_i: now i=4,j=0,k=0 and x = 000000100...
And if you increment_k then it works on the other bits:
ijkijkijk
increment_k: now i=4,j=0,k=1 and x = 001000100...
increment_k: now i=4,j=0,k=2 and x = 000001100...
increment_k: now i=4,j=0,k=3 and x = 001001100...
increment_k: now i=4,j=0,k=4 and x = 000000101...