ASM 32bit -> 64bit

Just starting out? Need help? Post your questions and find answers here.
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

ASM 32bit -> 64bit

Post by grabiller »

Hello,

This is my first message on this forum, so hi to everyone :)

I'm no ASM coder but I use a little trick from a message posted on this forum to retrieve the String pointer of a string:

Code: Select all

Macro StrToPtr( var, ptr )
EnableASM
  LEA eax, var
  MOV ptr, eax
DisableASM
EndMacro

mystr.s      = ""
*pstr.String = 0
StrToPtr( mystr, *pstr )

*pstr\s + "Hello"

Debug mystr ; "Hello"
However, this only works for 32bit compilation.

Could someone here be kind enough to show me / explain to me the required 64bit version ?

Thanks a lot in advance.
Guy.
guy rabiller | radfac founder / ceo | raafal.org
Fred
Administrator
Administrator
Posts: 18161
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: ASM 32bit -> 64bit

Post by Fred »

You can try to replace 'eax' with 'rax', it should do the trick. 'rax' is the 64 bit equivalent of 'eax'
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: ASM 32bit -> 64bit

Post by grabiller »

Fred wrote:You can try to replace 'eax' with 'rax', it should do the trick. 'rax' is the 64 bit equivalent of 'eax'
Yes it works.

Thanks a lot Fred ! :)

Cheers,
Guy.
guy rabiller | radfac founder / ceo | raafal.org
User avatar
SPP
User
User
Posts: 44
Joined: Sun Mar 04, 2007 10:34 am
Location: BCN - SPAIN

Re: ASM 32bit -> 64bit

Post by SPP »

Hi Guy,

Sorry for my curiosity (and for my english) but i think that you can do the same without ASM:

mystr.s = ""
*stradd = @mystr
*pstr.String = @*stradd
*pstr\s = "hello"
Debug mystr

although may be i'm in error and you don't need it

Best regards
The PB community is great... nice to meet you!
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: ASM 32bit -> 64bit

Post by grabiller »

Hello SPP,

Your exemple works 'as is' but in the context of my application, this make it crash.

I'm passing the *ptr variable as an argument to a procedure wich is modifying the string.

This is the procedure in question :

Code: Select all

Procedure.size_t vnp_raw_unpack_string( *buffer, *pstr.String, max_size.size_t )
  If *buffer = 0 Or *pstr = 0 : ProcedureReturn 0 : EndIf
  Protected str_tmp.s = PeekS( *buffer, max_size, #PB_UTF8 )
  *pstr\s + str_tmp
  ProcedureReturn StringByteLength( str_tmp, #PB_UTF8 ) + 1
EndProcedure

mystr.s = "" : *pstr.String = 0 : StrToPtr( mystr, *pstr) ; ( ASM Macro )

vnp_raw_unpack_string( *buffer, *pstr, 1000 )

; ( *buffer beeing memory allocated with some UTF-8 string. )
I'm not sure why your way is crashing the application, actualy, but with the ASM macro it works perfectly well.

Cheers,
Guy.
guy rabiller | radfac founder / ceo | raafal.org
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: ASM 32bit -> 64bit

Post by luis »

Uhmmm... I would try this way (32/64 bit)

Code: Select all

Macro StrToPtr(var, ptr)
 ptr = @var
 ptr = @ptr  - SizeOf(Integer)
EndMacro


mystr.s      = ""
*pstr.String = 0

StrToPtr(mystr, *pstr)
*pstr\s + "Hello"

Debug *pstr 
Debug mystr

You need to come back with the pointer inside the structure to point to the structure's base address.

At least that's sound reasonable to me :)

Does it work in your code ?
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: ASM 32bit -> 64bit

Post by luis »

It seem to work :)

Code: Select all

Macro StrToPtr(var, ptr)
ptr = @var
ptr = @ptr  - SizeOf(Integer)
EndMacro

Procedure.i vnp_raw_unpack_string(*buffer, *pstr.String, max_size.i )
  If *buffer = 0 Or *pstr = 0 : ProcedureReturn 0 : EndIf
  Protected str_tmp.s = PeekS(*buffer, max_size, #PB_UTF8 )
  *pstr\s + str_tmp
  ProcedureReturn StringByteLength( str_tmp, #PB_UTF8 ) + 1
EndProcedure


buffer$ = "tanto va la gatta al lardo che ci lascia lo zampino"

mystr.s = "" : *pstr.String = 0 : StrToPtr( mystr, *pstr) ; ( ex ASM Macro )

vnp_raw_unpack_string(@buffer$, *pstr, 1000)

Debug mystr
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: ASM 32bit -> 64bit

Post by ts-soft »

@luis
your code is incorrect, you write in none allocate memory!

Enable purifier to see the error.

greetings - Thomas
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: ASM 32bit -> 64bit

Post by luis »

Yup, you are right, the offset was 4 bytes off compared to the asm macro :(

I don't know why at this point, but changing the macro this way seem to work (at least purifier seems happy)

Code: Select all

Macro StrToPtr(var, ptr)
 ptr = @var
 ptr = @ptr - (4 + SizeOf(Integer))
EndMacro

Code: Select all

Macro StrToPtr(var, ptr)
 ptr = @var
 ptr = @ptr - (4 + SizeOf(Integer))
EndMacro


Procedure.i vnp_raw_unpack_string(*buffer, *pstr.String, max_size.i )
  If *buffer = 0 Or *pstr = 0 : ProcedureReturn 0 : EndIf
  Protected str_tmp.s = PeekS(*buffer, max_size, #PB_UTF8 )
  *pstr\s + str_tmp
  ProcedureReturn StringByteLength( str_tmp, #PB_UTF8 ) + 1
EndProcedure


buffer$ = "tanto va la gatta al lardo che ci lascia lo zampino"

mystr.s = "" : *pstr.String = 0 : StrToPtr( mystr, *pstr) ; ( ex ASM Macro )

vnp_raw_unpack_string(@buffer$, *pstr, 1000)

Debug mystr
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: ASM 32bit -> 64bit

Post by ts-soft »

This example works only with purifier enabled? Without purifier i become a empty string :o
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: ASM 32bit -> 64bit

Post by luis »

ts-soft wrote:This example works only with purifier enabled? Without purifier i become a empty string :o

LOL, so that's the reason why I wrote above "I don't know why". After all I believied to have checked the returned pointers were the same... The purifier seem to alter something, and after all considering these are pb internals it can have all the rights to do so.


So, this code (the original one) seems correct after all:

Code: Select all

 
Macro PB_StrToPtr(var, ptr)
 ptr = @var
 ptr = @ptr - SizeOf(Integer)
EndMacro


CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
Macro ASM_StrToPtr( var, ptr )
EnableASM
  LEA eax, var
  MOV ptr, eax
DisableASM
EndMacro
 CompilerElse   
Macro ASM_StrToPtr( var, ptr )
EnableASM
  LEA rax, var
  MOV ptr, rax
DisableASM
EndMacro 
CompilerEndIf


mystr.s      = "ASM_"
*pstr.String = 0
ASM_StrToPtr( mystr, *pstr )

Debug *pstr
*pstr\s + "Hello"
Debug mystr ; "Hello"


mystr.s      = "PB_"
*pstr.String = 0
PB_StrToPtr( mystr, *pstr )

Debug *pstr
*pstr\s + "Hello"
Debug mystr ; "Hello"
It works ok and results in the same pointer returned from the assembly macro, but using PB code instead of asm seem to make it "tamper-able" by the purifier.

In the end, considering the purifier it's a nice thing to have, it's better to stick to the asm version.

Interesting nevertheless.

Hey, I could be wrong but it seem that way!
"Have you tried turning it off and on again ?"
A little PureBasic review
Post Reply