Here are some conventions about Asm calls: First get addresses: always do something like $ "UASM" palparse ?SKIP :: 3DROP gasp, EXIT ; EVAL ?SKIP :: gasp, EXIT ; don't rely on ROMPTRs, since they might be renumbered in another version. Then you can call them at any time, provided that - before calling, you set R4[A] equal to the first entry of the lib data you get thanks to UASM (this is the address of data of Upar). - your calling only uses one stack entry, ie CODE .. blabla which doesn't push anything, or else pops it.. .. Compute Asm_Ufoo address in C.. GOSUB =PC=C GOC error .. life after the call GOSBVL =GETPTRLOOP error A=C A P= 0 GOSBVL =GETPTR GOVLNG =Errjmp =PC=C PC=C ENDCODE is okay (this is a minimum ;-), but not more ! (Usinagaz uses 5 stack levels !) - you don't even hope your registers will be preserved, except R3[W] (Actually, my builder automatically checks that Usinagaz don't ever think about it), so that you can save your own program data address. - you don't store objects after Upar, ie after it in menu's order, or in port 0. If you do, you'll just have to recall UASM to get the UASM structure right (it is inside Upar !) - you don't write your own interrupt handler address in #8600D/#86017, but rather in #860012/#86001C (hp49 only) That said, as long as Upar & Usinagaz are not moved, you can manage memory as you need, Usinagaz only allocates data when called via (Sys-)RPL. Details of calling conventions are described in doc/asmcalls.txt, automatically generated from source code to avoid any missynchronization.