Chaine de caractère et HEAPALLOC

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Chaine de caractère et HEAPALLOC

Message par Backup »

mad a écrit :Comme marqué au dessus, pour ma part, je l'utilise pour la lisibilité du code...
oui , tres bien , moi je me contentais juste d'apporter une info, que tu n'avais peut etre pas ...
il est arrivé plein de topic, on sur un sujet , on rebondi sur un autre ...
Bien, le topic, comme le titre indique, c'est sur HeapAlloc() et la définition de variable de type string en allocation mémoire ou prise directement en variable automatique sur la pile...

Mais je pense, au vu de tes connaissances en assembleurs, que tu pourrais peut être m'expliquer le fonctionnement de HeapAlloc pour une variable de type string ?
tu utilise des termes, que franchement je ne connais pas .. ( plutot réservé au C non ? )

en tout cas lorsqu'on fait :

Code : Tout sélectionner

Structure date
    jour.s{2}
EndStructure
du point de vue code assembleur généré , il ne se passe rien de plus !
les {} doivent correspondre a une directive au linkage
il s'agit de reserver de la Ram pour la variable chaine , mais franchement, je sais pas ou
(pas sur la pile en tout cas !! pas de Push correspondant )

Code : Tout sélectionner

; Structure date
; jour.s{2}
; EndStructure
; 
; 
; EPB 
; 
_PB_EOP_NoValue:
  PUSH   dword 0
_PB_EOP:
  CALL  _PB_EndFunctions
  PUSH   dword [PB_MemoryBase]
  CALL  _HeapDestroy@4
  CALL  _ExitProcess@4
_PB_EndFunctions:
  RET
faudrai demander a Fred , ou Denis si tu passe dans le coin ??

ça doit peut etre faire appel a une librairie Purebasic,qui se charge de reserver de la memoire ..
car rien ne transparait dans la transformation du code Purebasic , en Assembleur

de là a affirmer que ce soit plus rapide .... pas sur
mad
Messages : 32
Inscription : mar. 24/nov./2009 10:34

Re: Chaine de caractère et HEAPALLOC

Message par mad »

Tu vois, si tu avais lu, tu saurais ...

Pour ma part, le Define je connaissait déja, merci c'est sympa ...

Donc maintenant, fini de rigoler, hein..., je vais te montrer ce qui ce passe "derrière"...
Du moins je vais essayer, car je n'ai pas ton niveau en assembleur Dobro..


Donc prenons l'exemple de quelqu'un qui marquerais un code du type...
Pour te simplifier la lecture je vais t'enlever un de tes cauchemars ... les Define d'accord ?

allez on y va...

Code : Tout sélectionner


toto.s

toto="toto"



On le compile et ensuite hop sur IDA ... et on regarde ....


Image

Nous pouvons nous apercevoir de l'appel "CALL sub_402030" qui correspond à la création de la variable toto, car ensuite il pousse le texte "toto" dedans.

En effet ce n'est pas une variable sur la pile, mais bien un appel... un appel ? allons voir ! hop on saute ...


Image


Et hop nous voici sur le moment de la création de la variable... ho ! un HeapAlloc dis donc !
Bah oui, pas de mystère, quand on ne connais pas la taille, on alloue de la mémoire.
Aller on saute a sur le HeapAlloc, pour voir, juste ...

Image


On peut s'apercevoir, qu'en fait il une allocation mémoire, et qu'il est possible de l'étendre autant que l'on veut, mais, c'est gourmand, car systématiquement il passe dans cette fonction, contenu dans la librairie MSVCRT.DLL, afin de pouvoir réalloué dynamiquement, la taille... Très gourmand...

---------------------------

Maintenant prenons l'exemple, d'une variable à taille définie...

On reprend notre programme ...

Code : Tout sélectionner

toto.s{255}

toto="toto"
on le compile ... et on l'ouvre avec le produit que maitrise Dobro parfaitement... IDA... 8)

Que ce passe t'il ?

Image

Bien c'est simple, déja pas d'appel HeapAlloc à l'horizon, en fait il "pousse" le tas jusqu’à la valeur défini par la déclaration grâçe au "jnz".
Une fois terminé, il remplira avec le texte "push offset...."

Nous pouvons nous apercevoir donc, ya pas photo, une taille de chaine de caractère définie à l'avance, c'est quand même plus rapide...

Donc pour les débutants, comme moi en Purebasic, attention, quand on veut gagner du temps, toujours utiliser des chaine de caractère a taille défini, ça va plus vite ... !

Je ne sais pas si je me suis bien exprimé, mais voilà, donc conclusion :

toto.s et toto$ = allocation mémoire, plus de lourdeur, fonctionne comme une allocation mémoire, utilise la librairie msvcrt.dll du système dans le cas d'un Windows
toto.s{255} = variable automatique, alloué sur le tas, plus rapide, mais obligatoirement défini par une taille.

Y'en avait un seul qui ma compris depuis le début ... c'est djes...

Voilà, tu vois Dobro, faire attention quand on lit un topic, de na pas trop déborder sur un autre sujet et de s'assurer que l'on a bien compris ce que la personne demandais...

Moi perso je m'arrête là, je voulais vous montrer donc, quelques chose que je pensais autrement, car j'avais moi même mal lu la docu PB...

En effet je pensais que en utilisant toto$="tutututu", il aurait une variable automatique de 8 caractères. Mais en fait non !
Du coup j'ai refais ma fonction avec des tailles fixe pour économiser la mémoire. Voilà voilà


FIN
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Chaine de caractère et HEAPALLOC

Message par Backup »

Ida , je ne connais pas ... c'est payant ... :wink:

quand au purebasic , j'attends de voir ce que tu vas nous faire ;)
mad
Messages : 32
Inscription : mar. 24/nov./2009 10:34

Re: Chaine de caractère et HEAPALLOC

Message par mad »

Bonjour Dobro, pour ma part j'utilise Purebasic dans un environnement professionnel, mais j'ai quelques petits programme que j'ai fais pour mes loisirs ...

Logiciel de station météo pour la marque DAVIS, Pilotage de raquette automatisé pour télescope, logiciel pour la gestion et le séquencement d'action (login script, machine, masterisation,etc...), et puis la MADLIB. En effet j'ai fais quelques fonctions que j'ai mutualisés afin de le réutiliser dans mes prochains programmes ..., bon j'en ai fais d'autre, mais ...

Et pour IDA, effectivement il est payant, mais c'est l'entreprise qui l'a acheté ...
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Chaine de caractère et HEAPALLOC

Message par Backup »

la MADLIB .. interressant , ça fais quoi ? :)


utile pour quel domaine d'application ?

non , je ne suis pas de la police, je m'interresse ;)

ps: en debugger j'ai mieux connu SoftICE a l'epoque de win 98 .....
j'utilise de temps en temps ollydbg , mais j'ai bien decroché ( je ne pratique plus le Nop et autre inversion de jnz ;)
mad
Messages : 32
Inscription : mar. 24/nov./2009 10:34

Re: Chaine de caractère et HEAPALLOC

Message par mad »

J'ai fais une UserLib, pour tout simplement étendre la "STL" de purebasic, à des fonctions que j'utilisais récursivement dans Purebasic
Genre les logs, accès base de registre, des mini serveur TCP pour des clients autonomes (Genre petit inventaire machine sur déclenchement, etc...)
Dernière modification par mad le mer. 11/avr./2012 9:46, modifié 1 fois.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Chaine de caractère et HEAPALLOC

Message par djes »

C'est une discussion intéressante, non ?

Mes deux cents concernant le "define" versus la première déclaration : c'est une question de façon de coder. PB donne le choix, aux programmeurs venant de plusieurs horizons. Il n'est pas un BASIC au sens strict. Le define se retrouve dans tous les langages de haut niveau avec déclaration explicite ; moi qui ait fait beaucoup de Pascal à une époque, j'utilise cette syntaxe quand je veux faire du code "propre". Je dirais que chaque solution a ses avantages et ses inconvénients.

Dobro préfère la déclaration systématique ; ça me fait penser à la notation hongroise, on sait toujours à quoi correspond une variable. Inconvénients : toujours taper l'extension ; et si on n'utilise pas le EnableExplicit, c'est risquer de passer à côté d'une variable oubliée/perdue dans le code, surtout quand on en a dans plusieurs fichiers.

Le define permet de retrouver ses petits dès le début du code, sans forcément les utiliser. Le define ne crée pas les variables (n'alloue pas de mémoire), donc si on ne les utilise pas, on ne perd pas de mémoire pour rien. Avec lui, on peut les classer, leur donner un nom en fonction les unes des autres, et on sait si le nom a déjà été utilisé ou pas. Inconvénient : rigueur, il faut se forcer à revenir au define pour déclarer ses variables, ça coupe un peu l'élan de programmation.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Chaine de caractère et HEAPALLOC

Message par Backup »

bon, et bien , bonne continuation sur Purebasic alors .. :)

et merci pour la leçon a propos de la réservation des variables :)


a ce propos , il existe d'autre moyen d'ecrire une valeur dans un endroit fixe

je pense a l'utilisation de la lib Memory ... mais je suppose que tu connais deja ;)


@Djes, oui , une histoire d'habitude ..
je n'ai connu que le Basic (depuis la préhistoire.... non declaration des variables en basic).. ceci explique cela :)

@Mad , mes sources assembleur proviennent du compilateur Purebasic lui meme ... du coup je n'ai pas acces a ce que fait le linker
les attributions Memoire pour les Variables, n'apparaissent pas ...
car c'est une librairie Purebasic qui le fait .. c'est exterieur au Code Purebasic
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Chaine de caractère et HEAPALLOC

Message par Backup »

Hum ! Dobro the retour ...


j'ai recup une version d'IDA histoire de coucher moins con

je regrette mais pour moi qui maitrise mal IDA ;)

j'ai tester ce code :

Code : Tout sélectionner

titi.s{255}
ben il y a bien un HeapALLOC qui ce fait !
il suffit de tracer le contenu du premier Sub qui suit le HeapCreate pour tomber dessus !

Image

je trace dedans , et que vois-je ??

Image

alors ? conclusion , quelque soit la methode , HeapALLOC est toujours utilisé ! ;)


enfin sous reserves .. je ne sais pas trop me servir de IDA 5.5

[reedit] ouffff! il est mortel ce IDA ... manque plus que l'interuption en plein prg ( comme Softice ) et ce serai parfait :)


[reedit]

meme avec ce code

Code : Tout sélectionner

; titi
titi.s{5}
titi.s="Dobro"
on vois bien ici le Sub avant l'attribution de la variable ( Sub 402020 )

Image

dans ce sub (402020) , le HeapAlloc apparait bien :)

Image
mad
Messages : 32
Inscription : mar. 24/nov./2009 10:34

Re: Chaine de caractère et HEAPALLOC

Message par mad »

Tu as fais le test d'une une procédure ?
genre :

Code : Tout sélectionner

Procedure.b test()
      titi.s{255}

titi = "--- monaffectation ---"


Endprocedure

test()

je crois, mais je ne suis pas sûr, que c'est un comportement différent. Moi perso, j'ai trouve comme tu as pus le constater le fameux JNZ, pour l'allocation sur la pile ...
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Chaine de caractère et HEAPALLOC

Message par Backup »

non , juste :

Code : Tout sélectionner

; titi
titi.s{5}
titi.s="Dobro"
que je compile , et je trace l'exe :)

c'est bizarre ... ( sous Seven 64 bit.. compilation 32 bits)
( compilateur local win32 ... version 5.5 IDA 32 bit)
mad
Messages : 32
Inscription : mar. 24/nov./2009 10:34

Re: Chaine de caractère et HEAPALLOC

Message par mad »

Je vais regarder ce soir, si je peux, si il existe une différence hors et dans une procédure.

Tu remarqueras tout de même, que le HeapAlloc dont je te parlais, c'est quand même un gros morceaux mine de rien... ça alourdis quand même un peu.

En C il est possible en définissant la taille d'un tableau de chaine, de faire sans heapalloc, et de l'utiliser simplement sur la pile.
mad
Messages : 32
Inscription : mar. 24/nov./2009 10:34

Re: Chaine de caractère et HEAPALLOC

Message par mad »

Je comprend pas, dans ton exemple, les tailles des HeapAlloc sont différentes du code purebasic...

Pour la config, pareil kifkif bourique, x64 compilation en X86 sur du 7, avec ida 5.2 ...

Mais essaye tout de même de passer dans une procédure tu verras il ne se comporte pas de la même manière.

Ce qui est intéressant c'est dès que tu inclus un type string, il créer automatiquement sur heap alloc, dès le début...

Par contre dans une procédure où tu as spécifié du type .s{12345}, là il va te créer une variable automatique.

En fait même si tu spécifies une taille, hors d'une procédure pour un type string, il s'en fou... C'est cela que cela voudrais dire ?

Inquiétant...

Tu verras fais le test dans une procédure, il te feras automatiquement une variable auto.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Chaine de caractère et HEAPALLOC

Message par Backup »

ouaip c'est clair ...

du reste, je pense que le temps serai important sur un grand nombre de declaration
de variable chaines ...

on peut faire autrement , par l'utilisation d'un buffer memoire (Lib Memory )
et l'utilisation des pointeurs

Code : Tout sélectionner

*MemoireID = AllocateMemory(5000)
  If *MemoireID
    Debug "Adresse de début de la zone mémoire de 5000 octets :"
    Debug *MemoireID
    PokeS(*MemoireID, "Stocke cette chaîne dans la zone mémoire")
    ;;;;;FreeMemory(*MemoireID)  ; sera également effectué automatiquement à la fin du programme
  Else
    Debug "Impossible d'allouer la mémoire demandée !"
  EndIf 

debug peeks(*MemoireID) ; ressort le contenue de l'espace memoire chaine

j'ai pas tracé ce code, mais a mon avis c'est surement plus rapide :)
En fait même si tu spécifies une taille, hors d'une procédure pour un type string, il s'en fou... C'est cela que cela voudrais dire ?
oui :)

enfin , il semble faire quand meme une HeapAlloc


ps: <merci de m'avoir fait connaitre IDA c'est tres puissant :)
mad
Messages : 32
Inscription : mar. 24/nov./2009 10:34

Re: Chaine de caractère et HEAPALLOC

Message par mad »

J'ai refais mon test initiale, et j'ai aussi un heapalloc du même type que le tien, avant l'appel de la procedure

Le code "source" :

Code : Tout sélectionner

EnableExplicit


Procedure  tyty()
	Define uuuu.s{123}

	uuuu = "---- allo ---"
EndProcedure


tyty()

Image

Dans le premier sub_402020, nous pouvons retrouver la même appel qu'avec ton exemple avec la taille de dwBytes à 10h

Image

Par contre plus bas, sub_40106E au moment de l'allocation, il fait sont jnz avec la taille qu'il ajuste avec le compteur "Push 7Bh" (123).

Image

Donc dans une procédure, il est possible d'allouer sur la pile directement


Je le connaissait pas avant non plus, et effectivement, il est vraiment pas mal pour faire de la rétro...

Mais bon 1000€ la licence je crois...
Répondre