Archive: Are the 20 Registers considered Global?


Are the 20 Registers considered Global?
  Greetings from a newbie!

I am writing my first ever function in NSIS and for the life of me I can't figure out from reading the manual whether I should ALWAYS push (in the beginning of the function) ALL registers used inside the function - and pop them at the end of the function?

If NSIS automatically saves all $0..$9 and $R0..$R9 variables on entering a function then restores them on returning, then I don't have to do that as a programmer.

But does NSIS really do that?

Thanks -- Phil


Yes, you have to manually push and pop the registers. Only push and pop the minimum you need, because it saves typing out all of them. Example:

Function GetHWNDDialog
;Push in order. For the sake of clarity, I used two variables.
Push $0
Push $1

;Gets the inner dialog HWND.
FindWindow $0 "#32770" 0 $HWNDPARENT

;Get a label's HWND on the inner dialog.
GetDlgItem $1 $0 1003

;Make it black.
SetCtlColors $1 0x000000
;If you want to return a value, put it in the first
;variable you pushed, in this function its $0 (StrCpy $0 $1)

;Pop off in opposite order.
Pop $1
Pop $0 ;To return a value, don't use pop here. Use Exch to
;swap the top of the stack with the variable.
FunctionEnd

If you have returned a value from your function, you pop it off the stack so that you can use it in the rest of your script (if you want to).

Hope this helps, Jason Ross aka JasonFriday13.

Thank you Jason.

So if I understand correctly, there is a bug in the following code, right?


DoesUserHaveAdminPrivileges

Push $R0
Call IsUserAdmin # see nsis.sourceforge.net/IsUserAdmin
Pop $R0
${If} $R0 == "false"
MessageBox MB_OK|MB_ICONEXCLAMATION "Must run with Admin Privileges"
Abort
${EndIf}
>FunctionEnd
>
Because although $R0 is pushed in the beginning and popped somewhere in the function, it is popped only to be modified by IsUserAdmin. So it must be popped again, at the end. Did I get this right?

the DumpState is very helpful to find the problem, when it comes to pushing and popping


Originally posted by fontale
...
Because although $R0 is pushed in the beginning and popped somewhere in the function, it is popped only to be modified by IsUserAdmin. So it must be popped again, at the end. Did I get this right?
Yes, but not necessarily. That function is definitely using a bad practice, but if it's documented properly it is usable.

ps. All variables in NSIS are global, even if defined in a function.

PaR