Page 6 sur 7

Publié : mer. 01/août/2007 23:06
par Ollivier
Minute! Pas en core fini!

Publié : mer. 01/août/2007 23:07
par Ollivier
Je vais te faire une ptite cuisine toute prête dans une belle procédure... Tu vas m'en donner des nouvelles :D

Publié : jeu. 02/août/2007 0:52
par Ollivier
La fonction Labels() te retourne une chaîne contenant tous les label de ton source séparés par le caractère ':'.
Il y a un caractère ":" à la fin de la chaîne, comme ça CountString(Chaine, ":") te donne direct le nombre de labels trouvés.
Tu récupère chaque label avec StringField()

Tu as deux paramètres à mettre:
* Le nom fichier basic et son extension
* Le chemin de PBCompiler.EXE (oui je sais je ne me suis pas foulé mais il est tard et je suis fatigué!)

Code : Tout sélectionner

Procedure.S Labels(Fichier.S, CompilerPath.S)
  ManagingPath.S = GetTemporaryDirectory()
  CompilerPath = RTrim(CompilerPath)
  If Right(CompilerPath, 1) <> "\"
    CompilerPath + "\"
  EndIf
  Sortie.S = ""
  If FileSize(ManagingPath + "PureBasic.ASM") <> -1
    DeleteFile(ManagingPath + "PureBasic.ASM")
  EndIf
  If RunProgram(CompilerPath + "PBCompiler.EXE", Fichier.S + " /COMMENTED", ManagingPath, #PB_Program_Wait)  
    Source.L = OpenFile(-1, ManagingPath + "PureBasic.ASM")
    Repeat
      LineCode.S = ReadString(Source)
      LLine = Len(LineCode)
      If Left(LineCode, 2) = "l_"
        Sortie + Right(LineCode, LLine - 2)
      EndIf
    Until Eof(Source)
    CloseFile(Source)
    If DeleteFile(ManagingPath + "PureBasic.ASM") = 0
      MessageRequester("Erreur", "Ne peut supprimer le fichier temporaire!")
    EndIf
  EndIf
  ProcedureReturn Sortie
EndProcedure

Publié : jeu. 02/août/2007 7:55
par Kwai chang caine
@OLLIVIER

J'ai tenté d'insérer ta SuperTurboMortelleProcedureDeLaMort dans ton ancien code, et comme dab, j'ai péché mon pere :oops:

Ca me donne ça
On a le tableau suivant :
0= Aie
1= Aioli
2= Fines herbes
3=

n° de la dernière chaîne créée : 2 (Fines herbes)
On défonce Fines herbes avec KillString() pas avec Tartare(x) = ""
n° de la dernière chaîne créée : 1 (Aioli)
n° de la prochaine chaine NUL : 0 (Aie)
Et je comprend pas bien le resultat : 8O
J'ai "encore glissé CHEF" quelque part :?
n° de la prochaine chaine NUL : 0 (Aie)
ça t'étonne que je comprenne pas, hein, ça t'étonne :lol: :lol:
NadineBoudin si les dieux m'avais doté d'un cerveau aussi gros que mon C.."Biiip" :?

Publié : jeu. 02/août/2007 8:03
par Backup
cool ! :D

Mais désolé , je ne reprendrai pas ton code pour plusieurs raisons :)

parceque d'abords je travaille sur le press papier pas sur fichier
(enfin pour la partie coloration BBC )

aussi parceque ma methode de travail est vraiment differente
j'aime bien etre l'auteur d'un algo jusqu'au bout :D
c'est le cas pour la coloration du colorer ! :D
je te remercie de t'etre penché dessus, (mais j'ai rien demandé moi :lol: )

par contre tu peux dévelloper ton prg , tu es bien parti :D
c'est bete de s'arreter la :D

Publié : dim. 05/août/2007 8:56
par Ollivier
@Dobro

Je ne sais pas si on peut appeler le code ci-dessus un vrai algo puisque le compilateur Pure fait 99% de la sauce! Disons que c'est un code de secours.

J'étais parti pour en faire un vite fait mais, comme tu le dis, il y a pleins de paramètres qui se réunissent et rendent la tâche ardue. Il faut maîtriser tous les noms de structure, procédure, instructions, etc... Rien ne doit être hasard pour déterminer si réellement un bout de chaîne dans le code source est un label ou pas!

Cette recherche m'a permis de découvrir qu'un label peut être inséré au beau milieu d'un lignes de code sans provoquer le moindre bug!

Pour un éditeur personnel, oui je compte bien en faire un perso, mais plutôt axé Tree.

Publié : mar. 07/août/2007 21:56
par Ollivier
Qu'est-ce qui t'arrive Kcc?

Publié : mer. 08/août/2007 8:27
par Kwai chang caine
Bonjour Ollivier, il est beau le toutou :D
Et en plus fan de baseball, c'est pas commun :lol:

Je disais :

J'ai tenté d'insérer ta SuperTurboMortelleProcedureDeLaMort :

Code : Tout sélectionner

Procedure.L NextNullString(*Index) ;(Ollivier spéciale dédicace à Kcc) 
! xor   eax,   eax                         ; eax = 0 
! mov   edi,  dword [p.p_Index]    ; edi = pointeur index 
! mov   ebx,  edi                         ; ebx = pointeur index 
! mov   ecx,  0xFFFFFFFF              ; ecx = 4Go 
! cld                                           ; cld = recherche de bas en haut 
! REPNE  SCASD ; >>> Une seule instruction ASM pour For: If PeekL() = 0: ExitFor: EndIf: Next 
! mov   eax,  edi                         ; eax = adresse trouvée 
! sub   eax,  ebx                         ; eax = adresse trouvé - adresse tableau 
! shr   eax,  2                             ; eax / 4 
! sub   eax,  3                            ; eax - 3 
ProcedureReturn 
EndProcedure 
dans ton ancien code :

Code : Tout sélectionner

Declare.L LastString(*Index) 
Declare KillString(Tmp.S(1), n.L) 

Dim Tartare.S(70) 

Tartare(0) = "Aie" 
Tartare(1) = "Aioli" 
Tartare(2) = "Fines herbes" 

Debug "On a le tableau suivant :" 
For i = 0 To 3 
Debug Str(i) + "= " + Tartare(i) 
Next 
Debug " " 


*Adr = LastString(@Tartare() ) 
Debug "n° de la dernière chaîne créée : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

Debug "On défonce " + Tartare(2) + " avec KillString() pas avec Tartare(x) = " + Chr(34) + Chr(34) 
KillString(Tartare(), 2) 

*Adr = LastString(@Tartare() ) 
Debug "n° de la dernière chaîne créée : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

Procedure.L LastString(*Index) ;(Ollivier spéciale dédicace à Kcc) 
! xor   eax,   eax              
! mov   edi,  dword [p.p_Index] 
! mov   ebx,  edi              
! mov   ecx,  0xFFFFFFFF 
! cld                        
! REPNE  SCASD ; >>> Une seule instruction ASM pour For: If PeekL() = 0: ExitFor: EndIf: Next 
! mov   eax,  edi 
! sub   eax,  ebx 
! shr   eax,  2 
! sub   eax,  2 
ProcedureReturn 
EndProcedure 

Procedure KillString(Tmp.S(1), n.L) 
  Tmp(n) = ""                  ; Fred gère la mémoire 
  *ptr = @Tmp()                ; on récupère l'adresse du tableau 
! xor   eax,  eax              ; on va écrire un LONG (=DWORD) = 0 
! mov   ebx,  dword [p.v_n]    ; on récupère le n de la chaîne 
! shl   ebx,  2                ; on le multiplie par 4 (car SizeOf(Long) = 4) 
! mov   edi,  dword [p.p_ptr]  ; on pointe le tableau 
! add   edi,  ebx              ; on se précise sur le pointeur à killer 
! stosd                        ; on le kille 
EndProcedure
Ce qui donne comme code :

Code : Tout sélectionner

Declare.L LastString(*Index) 
Declare KillString(Tmp.S(1), n.L) 
Declare NextNullString(*Index)

Dim Tartare.S(70) 

Tartare(0) = "Aie" 
Tartare(1) = "Aioli" 
Tartare(2) = "Fines herbes" 

Debug "On a le tableau suivant :" 

For i = 0 To 3 
 Debug Str(i) + "= " + Tartare(i) 
Next 

Debug " " 

*Adr = LastString(@Tartare()) 
Debug "n° de la dernière chaîne créée : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

Debug "On défonce " + Tartare(2) + " avec KillString() pas avec Tartare(x) = " + Chr(34) + Chr(34) 
KillString(@Tartare(), 2) 

*Adr = LastString(@Tartare()) 
Debug "n° de la dernière chaîne créée : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

*Adr = NextNullString(@Tartare()) 
Debug "n° de la prochaine chaine NUL : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

Procedure.L LastString(*Index) ;(Ollivier spéciale dédicace à Kcc) 

 ! xor   eax,   eax              
 ! mov   edi,  dword [p.p_Index] 
 ! mov   ebx,  edi              
 ! mov   ecx,  0xFFFFFFFF 
 ! cld                        
 ! REPNE  SCASD ; >>> Une seule instruction ASM pour For: If PeekL() = 0: ExitFor: EndIf: Next 
 ! mov   eax,  edi 
 ! sub   eax,  ebx 
 ! shr   eax,  2 
 ! sub   eax,  2 
 
 ProcedureReturn 
 
EndProcedure 

Procedure KillString(Tmp.S(1), n.L) 
 
 Tmp(n) = ""                  ; Fred gère la mémoire 
 *ptr = @Tmp()                ; on récupère l'adresse du tableau 
 ! xor   eax,  eax              ; on va écrire un LONG (=DWORD) = 0 
 ! mov   ebx,  dword [p.v_n]    ; on récupère le n de la chaîne 
 ! shl   ebx,  2                ; on le multiplie par 4 (car SizeOf(Long) = 4) 
 ! mov   edi,  dword [p.p_ptr]  ; on pointe le tableau 
 ! add   edi,  ebx              ; on se précise sur le pointeur à killer 
 ! stosd                        ; on le kille 
 
EndProcedure

Procedure.L NextNullString(*Index) ;(Ollivier spéciale dédicace à Kcc) 
 
 ! xor   eax,   eax                 ; eax = 0 
 ! mov   edi,  dword [p.p_Index]    ; edi = pointeur index 
 ! mov   ebx,  edi                  ; ebx = pointeur index 
 ! mov   ecx,  0xFFFFFFFF           ; ecx = 4Go 
 ! cld                              ; cld = recherche de bas en haut 
 ! REPNE  SCASD ; >>> Une seule instruction ASM pour For: If PeekL() = 0: ExitFor: EndIf: Next 
 ! mov   eax,  edi                  ; eax = adresse trouvée 
 ! sub   eax,  ebx                  ; eax = adresse trouvé - adresse tableau 
 ! shr   eax,  2                    ; eax / 4 
 ! sub   eax,  3                    ; eax - 3 
 
 ProcedureReturn 
 
EndProcedure 
Et cela me remonte le résultat 8O :

Code : Tout sélectionner

On a le tableau suivant :
0= Aie
1= Aioli
2= Fines herbes
3= 
 
n° de la dernière chaîne créée : 2 (Fines herbes)
On défonce Fines herbes avec KillString() pas avec Tartare(x) = ""
n° de la dernière chaîne créée : 1 (Aioli)
n° de la prochaine chaine NUL : 0 (Aie)
Et je comprend pas bien le resultat car la ligne :
n° de la prochaine chaine NUL : 0 (Aie)
Est pas juste, il me semble ??

Publié : mer. 08/août/2007 16:46
par Ollivier
Mes plus plates excuses... Teste ça, ça devrait aller mieux:

Code : Tout sélectionner

Declare.L LastString(*Index) 
Declare KillString(Tmp.S(1), n.L) 
Declare NextNullString(*Index) 

Dim Tartare.S(70) 

Tartare(0) = "Aie" 
Tartare(1) = "Aioli" 
Tartare(2) = "Fines herbes" 

Debug "On a le tableau suivant :" 

For i = 0 To 3 
 Debug Str(i) + "= " + Tartare(i) 
Next 

Debug " " 

*Adr = LastString(@Tartare()) 
Debug "n° de la dernière chaîne créée : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

Debug "On défonce " + Tartare(2) + " avec KillString() pas avec Tartare(x) = " + Chr(34) + Chr(34) 
KillString(@Tartare(), 2) 

*Adr = LastString(@Tartare()) 
Debug "n° de la dernière chaîne créée : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

*Adr = NextNullString(@Tartare()) 
Debug "n° de la prochaine chaine NUL : " + Str(*Adr) + " (" + Tartare(*Adr) + ")" 

Procedure.L LastString(*Index) ;(Ollivier spéciale dédicace à Kcc) 

 ! xor   eax,   eax              
 ! mov   edi,  dword [p.p_Index] 
 ! mov   ebx,  edi              
 ! mov   ecx,  0xFFFFFFFF 
 ! cld                        
 ! REPNE  SCASD ; >>> Une seule instruction ASM pour For: If PeekL() = 0: ExitFor: EndIf: Next 
 ! mov   eax,  edi 
 ! sub   eax,  ebx 
 ! shr   eax,  2 
 ! sub   eax,  2 
  
 ProcedureReturn 
  
EndProcedure 

Procedure KillString(Tmp.S(1), n.L) 
  
 Tmp(n) = ""                  ; Fred gère la mémoire 
 *ptr = @Tmp()                ; on récupère l'adresse du tableau 
 ! xor   eax,  eax              ; on va écrire un LONG (=DWORD) = 0 
 ! mov   ebx,  dword [p.v_n]    ; on récupère le n de la chaîne 
 ! shl   ebx,  2                ; on le multiplie par 4 (car SizeOf(Long) = 4) 
 ! mov   edi,  dword [p.p_ptr]  ; on pointe le tableau 
 ! add   edi,  ebx              ; on se précise sur le pointeur à killer 
 ! stosd                        ; on le kille 
  
EndProcedure 

Procedure.L NextNullString(*Index) ;(Ollivier spéciale dédicace à Kcc) 
  
 ! xor   eax,   eax                 ; eax = 0 
 ! mov   edi,  dword [p.p_Index]    ; edi = pointeur index 
 ! mov   ebx,  edi                  ; ebx = pointeur index 
 ! mov   ecx,  0xFFFFFFFF           ; ecx = 4Go 
 ! cld                              ; cld = recherche de bas en haut 
 ! REPNE  SCASD ; >>> Une seule instruction ASM pour For: If PeekL() = 0: ExitFor: EndIf: Next 
 ! mov   eax,  edi                  ; eax = adresse trouvée 
 ! sub   eax,  ebx                  ; eax = adresse trouvé - adresse tableau 
 ! shr   eax,  2                    ; eax / 4 
 ! sub   eax,  1                    ; eax - 3 
  
 ProcedureReturn 
  
EndProcedure 

Publié : mer. 08/août/2007 16:57
par Kwai chang caine
Des excuses, non mais est ce que tu rigole 8O

Tu me fais des codes à tomber par terre en defonçant le sol rien que pour moi, tu te tracasse a donf, et tu me fait des excuses pour une broutillounette de petite erreur :D

Sache que c'est moi qui te remercie mille fois de ton super code "RAMSES" (Because hieroglyphe :D )

ça marche trop de la balle (A pas confondre avec "Trop de balle" :oops: :lol: )

Merci encore et à bientot

Publié : mer. 08/août/2007 17:53
par Ollivier
Je vais faire un post sur les 2, 3 fonctions de chaîne en assembleur. Elles sont vieilles comme le monde et font des miracles.

Publié : jeu. 09/août/2007 8:36
par Kwai chang caine
Ah oui oui.
Je sais que certains freres du FORUM sont un peu frilleux quand à l'utilisation de l'ASM. Exemple mon ami DOBRO.

Mais je trouve que l'on en parle pas assez dans ce forum.

Je sais il y a une section ASM, mais quand j'ai cliqué dessus, j'ai eu l'impression que l'on parlait couture :lol:
Je comprend rien de rien.

Ce qui serait cool, c'est que quand cela le dit à quelqu'un c'est de donner des réponses en ASM si il est plus a l'aise, comme tu viens de le faire dans ce POST.
Cela n'empeche pas de faire cohabiter les deux solutions.
Apres tout si dieu a prévu que l'excelent PURE gere les deux en meme temps, c'est dommage de ne pas profiter ce cette fonction puissante.

Et puis peut etre que certaines choses ne peuvent se faire directement en PURE, ou bien sont trop lente, et comme dieu n'a que deux bras et a beaucoup de mal à répondre à toutes les demandes (rançon de la gloire) vous pourriez (Vous les ASMEURS) completer le GRAND PURE pour qu'il devienne encore plus puissant en attendant qu'une nouvelle fonction native nous arrive du ciel. :D

D'ailleur deux questions, si tu fait une procedure en ASM :
1/ est elle aussi rapide qu'une fonction NATIVE ?
2/est elle aussi rapide qu'une lib ?

Car les lib c'est super, mais on ne sait pas ce qu'il y a dedans la plupart du temps, et c'est normal car le forcené qui s'est tapé des heures de codage ne veux pas obligatoirement qu'on lui pique le fruit de son travail, et je le comprend.
Mais donc on ne sait pas ce qu'il y a dedans, si on a besoin que d'une ou deux fonctions de la lib, bah on est obligé de la mettre complete.
Si par malheur le "libeur" à fait une erreur (qui ne fait rien ne risque pas l'erreur), on est dépendant de lui seulement, pour la modif, alors que si c'est en ASM beaucoups de freres peuvent nous aider.
D'ailleur l'erreur est corrigé bien souvent avant, quand le code est posté, puisque tout le monde le voit.
Et puis il ne faut pas oublier toutes les libs que l'on a installé, par exemple si on va chez un copain ou sur une autre machine avec un code source = "Ping" fonction inconnue....

Bref, moi je suis mega POUR.
J'espere que je ne suis pas le seul.

En plus a force d'avoir des codes bien commenté comme les tiens en ASM on pourra au moins comprendre une ou deux instructions.
Enfin pour moi cela releverais du miracle, mais pour certains cela rajouterais une ligne a leur CV deja bien rempli.
Et cette ligne c'est quand meme le MAITRE des languages c'est pas rien. :wink:

Publié : jeu. 09/août/2007 10:52
par Ar-S
Salut KCC,
Bon ba pour l'ASM, des méchants tutos seraient les bienvenus car devant un code ASM je me sens comme un hyperactif au milieu d'un champ de mines :)
j'arrive bien à résoudre qques petits crackme/keygenme par ci par là ce qui me font comprendre un poil l'utilité de qques fonctions mais insérer de l'asm dans un prog pb tout en faisant en sorte que ça veuille dire quelque chose :) ...
Là je dis Image

Publié : jeu. 09/août/2007 11:11
par Kwai chang caine
Bah des tutos, je crois que y'en a dans le forum :roll:
http://www.purebasic.fr/french/viewforum.php?f=12

Mais c'est pour se mettre à l'ASM carrémént en apprenant du debut, et je crois que c'est pas simple.
Au debut de pure, SPH m'avait gentillement expliqué qu'il vallait mieux se mettre au C, car l'ASM c'etait pas de la tartelette et je veux bien le croire.

C'est super donc d'avoir prevu une rubrique ASM, mais c'est qu'on parle que d'ASM et quand on a un bleme en PURE, parfois on peut avoir une soluce en ASM et en pure ça ne gache rien.
Chacun choisi ce qu'il désire.
Je ne pense pas qu'avoir séparé les 2 languages ai que des avantages.
Tu va me dire y'a qu'a poser la question dans les 2 rubriques.
C'est aussi une solution.
Mais parfois on pose une question, puis c'est normal que tout le monde tente d'y repondre en PURE, mais un petit code en ASM a coté pour celui qui connait mieux l'ASM que pure ou qui pense que ce serait mieux pour cette fonction en ASM, je pense que ce serait un plus.

Je sais qu'au debut quand je suis arrivé, SPH repondait de la sorte au forum debutant, je n'y voyais aucun mal, puisque l'ASM fait partie integrante de pure, et comme je l'ai dit, 2 reponses valent mieux qu'une. Apres a chacun de choisir celle qui lui convient le mieux, PURE ou ASM.
Mais certains l'on envoyé bouler, en lui retorquant que c'etait un forum PURE.
Bien sur, il etait un peu arrogant, mais il voulait surement que faire le bien, enfin comme je l'ai dit, je venais d'arriver donc je ne connais pas l'histoire depuis le debut.
Bref, un melange des deux mondes au lieu d'une guerre ne pourrait que profiter à tout le monde.
Apres tout si la droite et la gauche on cohabité pourquoi pas PURE et l'ASM.
L'important c'est d'avoir des réponses à nos questions, et encore une fois 2 reponses sont toujours mieux qu'une :wink:

Publié : jeu. 09/août/2007 21:36
par Flype
L'assembleur ne répond pas à tous les problèmes ou tous les fantasmes.
c'est passionnant je dis pas. si on maitrise, ou qu'on a le temps de maitriser l'ASM ok.

Dans la réalité de l'entreprise où je bosse, çà n'aurait que des désavantages. temps de développement plus long (alors que c'est justement ce qu'il manque le plus), problèmes de portabilité, de difficulté de debugage, de maintenabilité, d'interopérabilité, et de gens compétents capables de reprendre les sources ASM des autres (ça c'est chaud)...

Enfin je dis çà, je suis peut-être jaloux en fait :lol:

Parce que c'est vrai qu'il y a plein de petits bouts de code qui méritent d'être codés en assembleur quand on cherche la vitesse (le seul vrai argument je pense), dans un jeu par ex ou pour un traitement lourd et répéter bref 'couteux'.

@FULGUROKWAI

Le fait de pouvoir mêler les deux en purebasic est un sacré confortà mon avis.
On écrit son programme tranquille en PB, et on place une fonction ou deux en ASM sans se prendre la tête. Beaucoup de PureBasiciens n'auraient probablement jamais touchés à l'ASM si PureBasic le proposait pas.

Et les 2 (PB vs ASM) ne sont pas si distincts que çà !
Le compilateur PB génère de l'ASM... Chacun de nos programmes est d'abord traduit 'magiquement' par Fred/Freak en assembleur. Le code ASM qu'on peut écrire dans un source est ainsi simplement recopié aux cotés du code pb traduit en ASM le tout donnant un programme totalement en ASM. Après c'est le travail du compilateur FASM de transformer le tout en exécutable.

Pour répondre à ta question sur la vitesse,
J'ai envie de dire que le gain de vitesse en ASM n'est pas systématiquement un dû.
Un bon algorithme bien écrit en PureBasic sera toujours plus rapide qu'un algo pourri écrit en ASM. Par contre, un code 'bien écrit et bien pensé' en ASM sera forcément plus rapide, et souvent la différence est impressionnante.