It is currently Fri Dec 13, 2019 3:20 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: how to push local variables onto the stack?
PostPosted: Fri Jul 31, 2015 5:52 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Jun 04, 2015 7:10 am
Posts: 1673
I just found out that we cant push local variables :(
The helpfile says:
Quote:
Local variables in PureBasic are directly indexed by the stack pointer, which means if the stack pointer change via an ASM instruction (like PUSH, POP etc..) the variable index will be wrong and direct variable reference won't work anymore.

But it doesn't give any suggestions or workarounds

I hope you won't tell me i have to use a debugger and manually fiddle around with "p.v_var+4", "p.v_var+8" etc trying to get the stack alignment correct as that is a really ugly laborious slow and errorprone way, and i thought that is job for the compiler not programmer so i hope Purebasic has a practical solution :). Or if we cant use local variables should I simply be using a different type, like Global, or...?
Thankyou for any tips

Code:
Procedure Test()
  Protected xvar1.l = $11
  Protected xvar2.l = $22
  Protected xvar3.l = $33 
  PrintN("xvar1=" + Hex(xvar1))  ;$11
  PrintN("xvar2=" + Hex(xvar2))  ;$22
  PrintN("xvar3=" + Hex(xvar3))  ;$33
  EnableASM
  ! int 3
  ! push dword [p.v_xvar1]  ;$11
  ! push dword [p.v_xvar2]  ;should be $22 but is $11
  ! push dword [p.v_xvar3]  ;should be $33 but is $11
  DisableASM
EndProcedure
 
OpenConsole()
Test()

_________________
Thankyou to all the coders who generously helped & encouraged me in the nearly 2yrs when i was welcome here,
it was a tremendous privilege. I learned a lot. I wish you and your families all the best and success for the future.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Fri Jul 31, 2015 6:08 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 3545
Location: Netherlands
You can usually work around it by moving values first to registers and push those or use mov to put values on the stack.
In this case I have no idea what to advice since I have no idea what you are trying to do. Pushing three variables without correcting the stack pointer seems like asking for problems to me.

_________________
macOS 10.15 Catalina, PB 5.71 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Fri Jul 31, 2015 6:27 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Jun 04, 2015 7:10 am
Posts: 1673
for example to push parameters before calling the address of an API function directly

_________________
Thankyou to all the coders who generously helped & encouraged me in the nearly 2yrs when i was welcome here,
it was a tremendous privilege. I learned a lot. I wish you and your families all the best and success for the future.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Fri Jul 31, 2015 7:05 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 3545
Location: Netherlands
Two possible workarounds.
Code:
Procedure.i calloc(num, size)
  !extrn _calloc
  !mov eax, [p.v_size]
  !mov ecx, [p.v_num]
  !push eax
  !push ecx
  !call _calloc
  !add esp, 8
  ProcedureReturn
EndProcedure

Debug calloc(4, 50)


Code:
Procedure.i calloc(num, size)
  !extrn _calloc
 
  !mov eax, [p.v_size]
  !mov [esp - 4], eax
 
  !mov eax, [p.v_num]
  !mov [esp - 8], eax
 
  !sub esp, 8
  !call _calloc
  !add esp, 8
 
  ProcedureReturn
EndProcedure

Debug calloc(4, 50)

_________________
macOS 10.15 Catalina, PB 5.71 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Fri Jul 31, 2015 7:09 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Jun 04, 2015 7:10 am
Posts: 1673
Excellent, thankyou very much! :)
It seems I can also use the Prototype function for this, but i like to also know how to do it properly myself!

_________________
Thankyou to all the coders who generously helped & encouraged me in the nearly 2yrs when i was welcome here,
it was a tremendous privilege. I learned a lot. I wish you and your families all the best and success for the future.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Sun Aug 02, 2015 9:14 am 
Offline
Addict
Addict
User avatar

Joined: Sat Aug 15, 2009 6:59 pm
Posts: 1252
You just need to add the right value to the variables stack index.
On x86 that would be 4 byte per push and on x64 8 byte per push.

So something like this:
Code:
Procedure Test()
 
  Protected TestVar1
  Protected TestVar2
 
  TestVar1 = 1
  TestVar2 = 2
 
  !push qword [p.v_TestVar1]
  !push qword [p.v_TestVar2+8]
 
 
  !pop qword [p.v_TestVar2+8]
  !pop qword [p.v_TestVar1]
 
 
  Debug TestVar1
  Debug TestVar2
   
EndProcedure

Test()


If you push something to the stack, the stack pointer changes and you need to correct local variable accesses like that.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Sun Aug 02, 2015 9:45 am 
Offline
Addict
Addict
User avatar

Joined: Thu Jun 04, 2015 7:10 am
Posts: 1673
the PB compiler should do be doing those adjustments for us before it sends to FASM. How it is at the moment is very restrictive as you have to keep track of every variable in its position on the stack, and then never change the code, or if you do you have to restart and debug it all again, yucky!

_________________
Thankyou to all the coders who generously helped & encouraged me in the nearly 2yrs when i was welcome here,
it was a tremendous privilege. I learned a lot. I wish you and your families all the best and success for the future.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Wed Sep 23, 2015 9:00 am 
Offline
Addict
Addict
User avatar

Joined: Thu Aug 07, 2003 7:01 pm
Posts: 3113
Location: United Kingdom
Can't you just copy the stack pointer to another register, then use that as the index to the local variables?

You will be able to push/pop from the stack as much as you like then (as long as the position is back to normal before the return).

_________________
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Wed Sep 23, 2015 4:05 pm 
Offline
Addict
Addict
User avatar

Joined: Tue Nov 09, 2010 10:15 pm
Posts: 1579
Keya wrote:
the PB compiler should do be doing those adjustments for us before it sends to FASM. How it is at the moment is very restrictive as you have to keep track of every variable in its position on the stack, and then never change the code, or if you do you have to restart and debug it all again, yucky!

The compiler does not "process" or "evaluate" your hand-written asm. It only outputs it directly.

PB uses [the register typically used as a frame pointer] for general use, to increase his number of registers available. This gives him another reg for optimizing his PB-generated code. I believe he investigated using it a few years back (IIRC, when looking into gosub/return within procs), and decided it was too much of an overhaul to implement.

Quote:
Can't you just copy the stack pointer to another register, then use that as the index to the local variables?

You will be able to push/pop from the stack as much as you like then (as long as the position is back to normal before the return).

That sounds like a great alternative, if you need more space than Wilbert's method allows, with limited registers.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Wed Sep 23, 2015 4:35 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 3545
Location: Netherlands
I believe it won't work.
Local variables are defined relative to the esp/rsp register.
For example
Code:
%define p.v_test esp+40

So if you change the stack register, you can't use the defined p.v_test anymore unless you compensate for it like Thorium suggested.
You can of course copy the stack register value to another register but you don't know what the relative offset should be.

_________________
macOS 10.15 Catalina, PB 5.71 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Sat May 06, 2017 2:49 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Nov 26, 2015 6:52 pm
Posts: 158
Location: Italy
Interesting thread...

May I ask why the use of "Protected" keyword?

My understanding is that this keyword is needed to create a local (ie: local to the procedure) variable having the same name as an already existing global var. But I see it often used in procedure using ASM, so I was wondering if there are some added benefits from using Protected" when no naming conflict with a global variable is present. Are there?

_________________
The PureBASIC Archives:
FOSS Resources:


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Sat May 06, 2017 8:43 pm 
Offline
Addict
Addict
User avatar

Joined: Tue Nov 09, 2010 10:15 pm
Posts: 1579
Tristano wrote:
Interesting thread...

May I ask why the use of "Protected" keyword?

My understanding is that this keyword is needed to create a local (ie: local to the procedure) variable having the same name as an already existing global var. But I see it often used in procedure using ASM, so I was wondering if there are some added benefits from using Protected" when no naming conflict with a global variable is present. Are there?


It is good practice to always use protected (local) variables within procedures, because you never know when you might reuse the code in another program that might have a conflicting global var name. Or, you might improve your code...etc.


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Sat May 06, 2017 8:48 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Apr 30, 2009 5:23 pm
Posts: 308
Location: Côtes d'Azur, France
I am not sure to fully understand, forgive me if i am wrong.

Using pop and push is equivalent to increment/decrement (+/-4/8) Esp and Mov from [Esp+/-4/8] to register.
You can assume stack memory is in L1 cache (your local variables are part of the stack already), instead of pushing and poping, you would better Mov again you local variable in your register after you call function you need.

So, instead of

Code:
Protected xvar1.l = $11
Mov Eax,DWORD [p.v_xvar1]
...
Push Eax
...
Pop Eax

You can do
Code:
Protected xvar1.l = $11
Mov Eax,DWORD [p.v_xvar1]
...
Mov DWORD [p.v_xvar1],Eax
...
Mov Eax,DWORD [p.v_xvar1]


So you can create local variables and use them to store your registers instead of using push/pop, use Mov.

It will be as fast (or close enough) and safer.
Image

_________________
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.70 LTS


Last edited by Fig on Mon May 08, 2017 9:25 am, edited 2 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Mon May 08, 2017 9:06 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Nov 26, 2015 6:52 pm
Posts: 158
Location: Italy
Forgive my question, but I'm still learning FASM:

wilbert wrote:
I believe it won't work.
Local variables are defined relative to the esp/rsp register.
For example
Code:
%define p.v_test esp+40

... but you don't know what the relative offset should be.


... so local variables are macros, not labels?

This means that at each occurence of the (above) variable p.v_test its value is actually replaced by esp+40, thus making its value always realtive?

_________________
The PureBASIC Archives:
FOSS Resources:


Top
 Profile  
Reply with quote  
 Post subject: Re: how to push local variables onto the stack?
PostPosted: Mon May 08, 2017 9:19 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Thu Apr 30, 2009 5:23 pm
Posts: 308
Location: Côtes d'Azur, France
Yep, that's why using "push" (or changing Esp in any way) messes with local variables.

_________________
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.70 LTS


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye