ZoriaRPG, to answer your question in your commented lines: the ZScript calling convention is more or less equivalent to C's. The caller first pushes the return address onto the stack, then all of the function's explicit argument, and finally, if the function is a member function, the "this" pointer is implicitly pushed as the last argument.

The return value of the function is by convention stored in EXP1.

The callee, then, before it can return, must pop all of the arguments (including the "this" pointer) off of the stack. That's what the lines are doing that you've commented about. The ZASM instruction uses the top 4 entries of the stack, but leaves them untouched, so ZScript pops them off, then pops off the return address and jumps to it. You could use NUL instead of EXP2 for these pops if you wanted.

The reason EXP2 is used as scratch space instead of EXP1 is simply to avoid accidentally tampering with the return value of the function.