Just starting out? Need help? Post your questions and find answers here.
sys64802
Enthusiast
Posts: 105 Joined: Sat Sep 12, 2015 6:55 pm
Post
by sys64802 » Sun Jan 24, 2016 12:07 pm
@Ramses800
As explained above, better to use this variant:
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
The other one using a fixed esp offset is just wrong, or at least not prudent.
But really, no, is wrong.
Ramses800
User
Posts: 27 Joined: Wed Nov 05, 2014 3:12 pm
Location: Sweden
Post
by Ramses800 » Sun Jan 24, 2016 4:26 pm
Good point, sys64802! Thanks for the input!
Former VB6 developer adventuring in a brave, new Purebasic world!
Demivec
Addict
Posts: 4091 Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA
Post
by Demivec » Mon Nov 29, 2021 1:30 am
Here is an update to the previous code that sets the DataSection read pointer. This one also returns the previous pointer's value.
Code: Select all
Procedure RestoreEx (*address)
;sets DataSection read pointer to *address and returns previous DataSection read pointer
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
!mov ecx, [PB_DataPointer]
!mov eax, [p.p_address]
!mov [PB_DataPointer], eax
!mov eax, ecx
CompilerElse
!mov rcx, [PB_DataPointer]
!mov rax, [p.p_address]
!mov [PB_DataPointer], rax
!mov rax, rcx
CompilerEndIf
ProcedureReturn
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
;demo
DataSection
Data.i 1, 2, 3, 4, 5, 6, 7
obj:
Data.i 1001, 2002, 3003, 4004, 5005, 6006, 7007
EndDataSection
Define var, i, oldReadPtr
For i = 1 To 3
Read.i var
Debug var
Next
oldReadPtr = RestoreEx(?obj)
Debug "oldPtr =" + oldReadPtr
For i = 1 To 3
Read.i var
Debug var
Next
oldReadPtr = RestoreEx(oldReadPtr)
Debug "oldPtr =" + oldReadPtr
For i = 1 To 3
Read.i var
Debug var
Next
CompilerEndIf
skywalk
Addict
Posts: 4003 Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA
Post
by skywalk » Sat Feb 12, 2022 11:23 pm
Ok, this ASM worked great but now is time to try PB6 C backend.
How to read a DataSection within a procedure parameter containing the data label?
Code: Select all
Procedure RestoreX(DataLabel.i)
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x64
!MOV rax, [p.v_DataLabel] ; instead of -> !MOV rax, [rsp+64]
!MOV [PB_DataPointer], rax
CompilerCase #PB_Processor_x86
!MOV eax, [p.v_DataLabel] ; instead of -> !MOV eax, [esp+8]
!MOV [PB_DataPointer], eax
CompilerDefault
MessageRequester("RestoreX", "Unknown Processor.", #MB_ICONERROR)
CompilerEndSelect
EndProcedure
; Example use within a procedure.
Procedure Do1()
RestoreX(?ds_MyDatasectionStuff)
Read.i i
EndProcedure
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
idle
Always Here
Posts: 5097 Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand
Post
by idle » Sun Feb 13, 2022 3:17 am
Code: Select all
Procedure RestoreX(DataLabel.i)
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x64
!MOV rax, [p.v_DataLabel] ; instead of -> !MOV rax, [rsp+64]
!MOV [PB_DataPointer], rax
CompilerCase #PB_Processor_x86
!MOV eax, [p.v_DataLabel] ; instead of -> !MOV eax, [esp+8]
!MOV [PB_DataPointer], eax
CompilerDefault
MessageRequester("RestoreX", "Unknown Processor.", #MB_ICONERROR)
CompilerEndSelect
CompilerElse
!*pb_datapointer = v_datalabel;
CompilerEndIf
EndProcedure
; Example use within a procedure.
Procedure Do1()
RestoreX(?ds_MyDatasectionStuff)
Read.i i
Read.i i
Debug i
EndProcedure
DataSection
ds_MyDatasectionStuff:
Data.i 12345,23456,34567
EndDataSection
Do1()
skywalk
Addict
Posts: 4003 Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA
Post
by skywalk » Sun Feb 13, 2022 4:38 am
Thanks idle!
Very close, but the 1st element read back from the datasection is corrupted.
Code: Select all
Procedure RestoreX(datalabel.i)
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x64
!MOV rax, [p.v_datalabel] ; instead of -> !MOV rax, [rsp+64]
!MOV [PB_DataPointer], rax
CompilerCase #PB_Processor_x86
!MOV eax, [p.v_datalabel] ; instead of -> !MOV eax, [esp+8]
!MOV [PB_DataPointer], eax
CompilerDefault
MessageRequester("RestoreX", "Unknown Processor.", #MB_ICONERROR)
CompilerEndSelect
CompilerElse
!*pb_datapointer = v_datalabel;
CompilerEndIf
EndProcedure
Procedure Do1(datalabel.i)
Protected.i i,d
RestoreX(datalabel)
For i = 1 To 4
Read.i d
Debug Str(i) + "," + Str(d)
Next i
EndProcedure
DataSection
ds_Stuff:
Data.i -1, 2, 3, 4
ds_Stuff2:
Data.i -2, 20,30,40
EndDataSection
Debug "ds_Stuff1"
Do1(?ds_Stuff)
Debug "ds_Stuff2"
Do1(?ds_Stuff2)
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
mk-soft
Always Here
Posts: 5409 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Sun Feb 13, 2022 1:00 pm
Without '*'
@skywalk: Please set your Bug-Report to [NoBug/DONE]
Code: Select all
Procedure RestoreX(datalabel.i)
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x64
!MOV rax, [p.v_datalabel] ; instead of -> !MOV rax, [rsp+64]
!MOV [PB_DataPointer], rax
CompilerCase #PB_Processor_x86
!MOV eax, [p.v_datalabel] ; instead of -> !MOV eax, [esp+8]
!MOV [PB_DataPointer], eax
CompilerDefault
CompilerError "RestoreX: Unknown Processor."
CompilerEndSelect
CompilerElse
!pb_datapointer = v_datalabel;
CompilerEndIf
EndProcedure
Procedure Do1(datalabel.i)
Protected.i i,d
RestoreX(datalabel)
For i = 1 To 4
Read.i d
Debug Str(i) + "," + Str(d)
Next i
EndProcedure
DataSection
ds_Stuff:
Data.i -1, 2, 3, 4
ds_Stuff2:
Data.i -2, 20,30,40
EndDataSection
Debug "ds_Stuff1"
Do1(?ds_Stuff)
Debug "ds_Stuff2"
Do1(?ds_Stuff2)
skywalk
Addict
Posts: 4003 Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA
Post
by skywalk » Sun Feb 13, 2022 5:18 pm
Thanks!
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
skywalk
Addict
Posts: 4003 Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA
Post
by skywalk » Mon Feb 14, 2022 4:30 am
Doh! Dropped my bug report too soon.
Small code works, but not in larger library. How to debug this?
pbcompilerc wrote: 21617 lines processed.
Error: Assembler
error: 'pb_datapointer' undeclared (first use in this function); did you mean 'pb_mapitem'?
pb_datapointer = v_datalabel;
^~~~~~~~~~~~~~
pb_mapitem
purebasic.c
1: note: each undeclared identifier is reported only once for each function it appears in
Code: Select all
static integer f_restorex(integer v_datalabel); //<-- Line 989
// Procedure RestoreX(datalabel.i)
static integer f_restorex(integer v_datalabel) {
integer r=0;
//
// CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
// !pb_datapointer = v_datalabel;
pb_datapointer = v_datalabel; //<-- Line 14666
// CompilerEndIf
// EndProcedure
r=0;
end:
return r;
}
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
idle
Always Here
Posts: 5097 Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand
Post
by idle » Mon Feb 14, 2022 7:31 pm
Have you dumped the c maybe it's renamed.
skywalk
Addict
Posts: 4003 Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA
Post
by skywalk » Mon Feb 14, 2022 8:15 pm
Yes, but dumping C is with pbcompilerc.exe on command line.
I do not know where the IDE compilation puts the amalgamated C file?
The line numbers are slightly different from IDE compile to command line compile because I cannot load resource and images from command line.
Inspecting the command line C file, it did not rename the variable.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
kenmo
Addict
Posts: 1967 Joined: Tue Dec 23, 2003 3:54 am
Post
by kenmo » Tue Feb 15, 2022 5:26 pm
I know this is an old topic, but I must ask... Why all the effort to use inlined ASM/C to manipulate the PB internals?
Once you're beyond the basic usage of Restore and Read, why not just use pointers and Peek?
It just seems strange to use ASM/C manipulation when you can accomplish it with regular PB code and maybe a few helper procedures.
skywalk
Addict
Posts: 4003 Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA
Post
by skywalk » Tue Feb 15, 2022 5:44 pm
Quite the opposite.
2 lines for ASM and 1 line for C backend, and we can use native Read.x within Procedures.
Of course, I would use the pointer approaches if these simpler alternatives were not available.
The same can be said of all PB use.
I use SendMessage() for some gui affects.
I use PB native and custom SQLite api commands.
Whatever gets the job done reliably.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum