without knowing the memory address ahead of time, you could patch direct references while the QBASIC programming is running, prior to executing the routine.
I even wrote a tool to accomplish this:
Be advised that I have not been maintaining the tool, and as you can see, it currently has at least one unfixed bug. I no longer trust the method or care enough about the tool to maintain it.
But just to demonstrate what I am talking about:
so that the address of "npars" is discovered at runtime, and patched.
Like I said, I no longer advocate this method.
The two methods I tend to use now are the stack method, with which you seem to be already familiar, and the method of having the code discover its own location, and use that as a reference point. This is demonstrated in my tutorial posted in this forum.
Example code from the tutorial:
sub bx,byte 0x3
mov al,[byte bx+_data]
mov [byte bx+_data],al
It's not a direct reference, but still, it works...