a) Is simple: test before you push, not after. At the moment, you read the value, poush it, and then decide to repeat. You need to read it, test, it if it's zero exit the loop, otherwise push and go round again.
b) I'm not at all familiar with the assembly code: so I can't be precise. But ... there are only two ways to pop as many items as you push:
b.1) Check for bottom of stack before you POP. If you are there, it;s empty, and you shouldn't POP any more. To make that work properly, you would need to store the initial stack pointer before you first PUSH and check against that.
b.2) Use a counter so you know how many items you PUSHed. You can then POP that number off.
The second approach is probably easier.
c) No idea whatsoever, I suspect your CPU / assembler is a bit made up specifically for your homework! It'll be in the instruction set your teacher gave you, somewhere. If I had to guess, I'd assume it's something like
CPY IO R0
but that could be completely wrong.