restore label as a parameter to a procedure?
-
- Enthusiast
- Posts: 732
- Joined: Fri Jul 14, 2006 8:53 pm
- Location: Malta
- Contact:
restore label as a parameter to a procedure?
I had a macro to populate an array using
Restore label
::
::
::
label:
can label be used as a paremeter in a procedure AND restore work with a variable?
cheers
Restore label
::
::
::
label:
can label be used as a paremeter in a procedure AND restore work with a variable?
cheers
I may not help with your coding
Just ask about mental issues!
http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
Just ask about mental issues!
http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
-
- Enthusiast
- Posts: 732
- Joined: Fri Jul 14, 2006 8:53 pm
- Location: Malta
- Contact:
thanks
I may not help with your coding
Just ask about mental issues!
http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
Just ask about mental issues!
http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
Either use a macro or...
If you alter the procedure's parameters, just make sure that address is the first parameter.
Code: Select all
Procedure myRestore(address)
!MOV EAX, [ESP+PS0]
!MOV [PB_DataPointer],EAX
EndProcedure
a = ?NumericalData2
myRestore(a)
Read.l a
Read.l b
Debug a
End
DataSection
NumericalData1:
Data.l 100, 200
NumericalData2:
Data.l 1000, 2000
EndDataSection
I may look like a mule, but I'm not a complete ass.
-
- Enthusiast
- Posts: 732
- Joined: Fri Jul 14, 2006 8:53 pm
- Location: Malta
- Contact:
many thanks
I hadnt even thought of how to go around it yet
was more worried about the steaks!
cheers
I hadnt even thought of how to go around it yet
was more worried about the steaks!
cheers
I may not help with your coding
Just ask about mental issues!
http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
Just ask about mental issues!
http://www.lulu.com/spotlight/kingwolf
http://www.sen3.net
Re: restore label as a parameter to a procedure?
Very cool srod!
This helped me solve my autogenerating menu problem.
Any chance this will make it as a PureBasic feature?
Or is this a limitation of single pass compiler (same reason for putting declares up top)?
I am autogenerating my menus based on elements/instructions in the DataSection.
My approach needs to pass the Data Label Address into a procedure.
Code fragment here...
I can post the whole thing if anybody cares. Really only makes sense if you have large menus > 25 entries and nested etc.
I type in the menu constructs in the DataSection and the code builds it straight away.
Then, to handle the menu events, I copy and paste the data.s sections into a select case block.
The cases are strings, but it is self-documenting nonetheless.
I am now trying to autogenerate gadgets/windows based on instructions in the DataSection.
This helped me solve my autogenerating menu problem.
Any chance this will make it as a PureBasic feature?
Or is this a limitation of single pass compiler (same reason for putting declares up top)?
I am autogenerating my menus based on elements/instructions in the DataSection.
My approach needs to pass the Data Label Address into a procedure.
Code fragment here...
Code: Select all
Procedure RestoreUsingVar(LabelAddress.i)
!MOV EAX, [ESP+PS0]
!MOV [PB_DataPointer],EAX
EndProcedure
Procedure.i MenuLoad(hWnd.i, mnuDataLabel.i, mnuID.i, Array mnu.MenuInfo(1))
Protected.i i,k,sck,fk,ri
Protected.s m1,m2,m3,sc
;Restore mnuDataLabel ;<--- This does not work :(
RestoreUsingVar(mnuDataLabel)
Repeat
With mnu(k)
Read.s m1
;~~~
; more code here
;~~~
EndWith
Until m1 = "E" Or m1 = ""
ProcedureReturn k
EndProcedure
nMenuLines = MenuLoad(hOne, ?Menu_DataOne, #mnuOne, mnuOne())
End
DataSection
Menu_DataOne:
; Type, Text, ShortCut(@ = Alt+, $ = Shift+, ^ = Ctrl+)
Data.s "T","&File"
Data.s "&Close","^Q"
Data.s "T","&Help"
Data.s "K","&About","F1"
Data.s "E" ; EndMenu
Menu_DataTwo:
Data.s "T","&File"
Data.s "&Close"
Data.s "T","&Help"
Data.s "K","&About","F1"
Data.s "E" ; EndMenu
EndDataSection
I type in the menu constructs in the DataSection and the code builds it straight away.
Then, to handle the menu events, I copy and paste the data.s sections into a select case block.
The cases are strings, but it is self-documenting nonetheless.
I am now trying to autogenerate gadgets/windows based on instructions in the DataSection.
Last edited by skywalk on Sun Nov 25, 2012 8:55 pm, edited 1 time in total.
Re: restore label as a parameter to a procedure?
EDIT: updated for C backend (6.01 B4)
Code: Select all
DataSection
Data.i 1, 2, 3
here:
Data.i 4, 5, 6
EndDataSection
Procedure RestoreEx (*ptr)
CompilerIf (#PB_Compiler_Backend = #PB_Backend_Asm)
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
!mov eax, [p.p_ptr]
!mov [PB_DataPointer], eax
CompilerElse
!mov rax, [p.p_ptr]
!mov [PB_DataPointer], rax
CompilerEndIf
CompilerElse
!pb_datapointer = (unsigned char *) p_ptr;
CompilerEndIf
EndProcedure
*here = ?here
RestoreEx (*here)
Read.i x
Debug x ; 4
Last edited by luis on Sat Feb 18, 2023 9:32 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: restore label as a parameter to a procedure?
Hi luis,
Does your code also work if there are XIncludeFiles?
It's been a while, but I was unable to use srod's Restore tip in that case.
Had to resort back to pointer math on the passed label when stepping through my DataSections in a Procedure.
Does your code also work if there are XIncludeFiles?
It's been a while, but I was unable to use srod's Restore tip in that case.
Had to resort back to pointer math on the passed label when stepping through my DataSections in a Procedure.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: restore label as a parameter to a procedure?
I'm not sure what the implications of that could been to affect that code.skywalk wrote:Hi luis,
Does your code also work if there are XIncludeFiles?
I don't see why shouldn't work but maybe I'm not considering something ?
Uhmm... for the original srod's routine probably the problem you encountered was it would work only if it's the first proc in your program, because the PS0 is really a constant generated by the compiler for each proc and the numeric part is incremented each time (roughly speaking). I assume at the time he adapted the output of the compiler.
So that code will not work if the proc is not the first (PS"0").
If I didn't make (didn't have ? what's the correct one ? LOL) some oversight this should work.
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: restore label as a parameter to a procedure?
Thanks luis!
You are correct. Your procedure works with XIncludeFiles where srod's use of "PS0" caused an incorrect label.
Wow, how simple a correction.
You are correct. Your procedure works with XIncludeFiles where srod's use of "PS0" caused an incorrect label.
Wow, how simple a correction.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: restore label as a parameter to a procedure?
Argg! I cannot figure this out?
Why do I get an IMA when using RestoreX_case()?
The only difference is CompilerCase statements?
Why do I get an IMA when using RestoreX_case()?
The only difference is CompilerCase statements?
Code: Select all
EnableExplicit
Macro NEXTDATA_Str(DataLabel)
; Use this if RestoreX() fails with newer PB versions.
*DataLabel + (MemoryStringLength(*DataLabel) + 1) * SizeOf(Character)
EndMacro
Procedure RestoreX_case(DataLabel.i)
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!mov eax, [esp+8]
!mov [PB_DataPointer], eax
;CompilerCase #PB_Processor_x64
CompilerDefault ;#PB_Processor_x64
!mov rax, [rsp+64]
!mov [PB_DataPointer], rax
CompilerEndSelect
EndProcedure
Procedure RestoreX_if(DataLabel.i)
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
!mov eax, [esp+8]
!mov [PB_DataPointer], eax
CompilerEndIf
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x64)
!mov rax, [rsp+64]
!mov [PB_DataPointer], rax
CompilerEndIf
EndProcedure
Procedure RestoreX_Luis(DataLabel.i)
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
!mov eax, [esp+8]
!mov [PB_DataPointer], eax
CompilerElse
!mov rax, [rsp+64]
!mov [PB_DataPointer], rax
CompilerEndIf
EndProcedure
Procedure.i MenuLoad(mnuDataLabel.i)
Protected.i *p = mnuDataLabel
Protected.s m$
;Restore mnuDataLabel ;<--- This does not work :(
Debug PeekS(mnuDataLabel)
Repeat
m$ = PeekS(*p): NEXTDATA_Str(p)
Debug m$
Until m$ = "E" Or m$ = ""
EndProcedure
Procedure.i MenuLoad_RestoreX(mnuDataLabel.i, Mode.i=0)
Protected.s m$
Select mode
Case 0
RestoreX_luis(mnuDataLabel)
Case 1
RestoreX_if(mnuDataLabel)
Case 2
RestoreX_case(mnuDataLabel)
EndSelect
Debug PeekS(mnuDataLabel)
Repeat
Read.s m$
Debug m$
Until m$ = "E" Or m$ = ""
EndProcedure
Debug "--- Menu2 ---"
MenuLoad(?Menu2)
Debug "--- RestoreX_Luis ---"
MenuLoad_RestoreX(?Menu2,0)
Debug "--- RestoreX_if ---"
MenuLoad_RestoreX(?Menu2,1)
Debug "--- RestoreX_case ---"
MenuLoad_RestoreX(?Menu2,2)
DataSection
Menu1:
Data.s "T","&File"
Data.s "&Close","^Q"
Data.s "E" ; EndMenu
Menu2:
Data.s "T","&Options"
Data.s "&None"
Data.s "E" ; EndMenu
EndDataSection
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: restore label as a parameter to a procedure?
There may be other differences.skywalk wrote:Argg! I cannot figure this out?
Why do I get an IMA when using RestoreX_case()?
The only difference is CompilerCase statements?
Just for completeness, here is the assembly code that was generated:
Code: Select all
; Procedure RestoreX_case(DataLabel.i)
macro MP0{
_Procedure0:
PS0=4
; CompilerSelect #PB_Compiler_Processor
; CompilerCase #PB_Processor_x86
; !MOV Eax, [esp+8]
p.v_DataLabel equ esp+PS0+0
MOV Eax, [esp+8]
; !MOV [PB_DataPointer], Eax
MOV [PB_DataPointer], Eax
;CompilerCase #PB_Processor_x64
; CompilerDefault ;#PB_Processor_x64
; EndProcedure
XOR eax,eax
_EndProcedure1:
RET 4
}
;
; Procedure RestoreX_if(DataLabel.i)
macro MP2{
_Procedure2:
PUSH ebx
PS2=8
; CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
; !MOV Eax, [esp+8]
p.v_DataLabel equ esp+PS2+0
MOV Eax, [esp+8]
; !MOV [PB_DataPointer], Eax
MOV [PB_DataPointer], Eax
; CompilerEndIf
; CompilerIf (#PB_Compiler_Processor = #PB_Processor_x64)
; EndProcedure
XOR eax,eax
_EndProcedure3:
POP ebx
RET 4
}
Using the variable name instead of an assumed offset works (only tested on x86):
Code: Select all
Procedure RestoreX_case(DataLabel.i)
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!MOV Eax, [p.v_DataLabel]
!MOV [PB_DataPointer], Eax
;CompilerCase #PB_Processor_x64
CompilerDefault ;#PB_Processor_x64
!MOV rax, [p.v_DataLabel]
!MOV [PB_DataPointer], rax
CompilerEndSelect
EndProcedure
Re: restore label as a parameter to a procedure?
Wow, I did a compare on the 2 ASM's but didn't catch that.
Is this related to the order of procedures or is the CompilerCase handled wrong?
I only stumbled on this since there isn't a CompilerElseIf.
Thanks, Demivec, I'll check tomorrow.
Is this related to the order of procedures or is the CompilerCase handled wrong?
I only stumbled on this since there isn't a CompilerElseIf.
Thanks, Demivec, I'll check tomorrow.
Re: restore label as a parameter to a procedure?
Thanks demivec, I don't know why at the time I didn't use the label instead of the fixed values
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: restore label as a parameter to a procedure?
Thanks so much for this tip, srod & luis!
Now I can hide strings as numbers in the data section easily together with a small app that generates the data section from any(well,ASCII) string.
Generate the data section and copy/paste it into the code that use the hidden string.
Code updated after remark from sys64802
Now I can hide strings as numbers in the data section easily together with a small app that generates the data section from any(well,ASCII) string.
Code: Select all
Procedure RestoreEx (*address)
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
!mov eax, [p.p_address]
!mov [PB_DataPointer], eax
CompilerElse
!mov rax, [p.p_address]
!mov [PB_DataPointer], rax
CompilerEndIf
EndProcedure
Procedure.s HiddenString(Label)
Define lStringLength.l, lCtrl.l
Define sReturn.s
Define lCharacter.l
; restore label
RestoreEx(label)
; read length of hidden string from first number
Read.l lStringLength
For lCtrl=1 To lStringLength
; read each number as character
Read.l lCharacter
sReturn=sReturn + Chr(lCharacter)
Next
ProcedureReturn sReturn
EndProcedure
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
MessageRequester("HiddenString(x86)",HiddenString(?MyHiddenString))
CompilerElse
MessageRequester("HiddenString(x64)",HiddenString(?MyHiddenString))
CompilerEndIf
DataSection
MyHiddenString:
; First number is the length of the string, the consecutive numbers are ASCII for each character
Data.l 21,78,111,119,32,121,111,117,32,99,97,110,39,116,32,115,101,101,32,109,101,33
EndDataSection
Code: Select all
Procedure.s GenerateDataSection(sLabelName.s,sString.s)
Define sString.s
Define lCtrl.l, lStringLength.l
Define sReturn.s
lStringLength=Len(sString)
sReturn="DataSection" + #CRLF$
sReturn= sReturn + sLabelName + ":" + #CRLF$
sReturn= sReturn + "Data.l " + Str(lStringLength)
For lCtrl=1 To Len(sString)
sReturn=sReturn + "," + Asc(Mid(sString,lCtrl,1))
Next
sReturn = sReturn + #CRLF$ + "EndDataSection"
ProcedureReturn sReturn
EndProcedure
Code updated after remark from sys64802
Last edited by Ramses800 on Sun Jan 24, 2016 4:25 pm, edited 2 times in total.
Former VB6 developer adventuring in a brave, new Purebasic world!