CallFunctionFast version ASM

Pour discuter de l'assembleur
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

CallFunctionFast version ASM

Message par cha0s »

Je suis actuellement sur une lib pour gérer des opérations de ce type :

Code : Tout sélectionner

$1 + ( cos(4) * pow(rand(), 2))
($1 correspond au premier paramètre comme en shell sous nux $1 ... $4....$x)

A la base sous forme de string je crée un pseudo-code que mon interpréteur va exécuter.
Seulement les fonctions utilisable sont nombre donc pour gagner du temp je me suis dit on va faire du CallFunctionFast avec les pointeurs des fonctions cos sin ect ect ... Mais hé stupeur CallFunctionFast ne supporte pas les doubles (mince mes scripts ne prenne que ce type de variable)

Pas de problème il y a l'ASM sauf que je suis un peu manchot dans le domaine
Je me retrouve donc avec ma fonction suivante

Code : Tout sélectionner

Procedure.d ExecuteFunction(*this.Function, *param)
  ProcedureReturn CallFunctionFast(*this\ptr, blablabla)
EndProcedure
A convertir en ASM et la je suis dessus depuis tout l'après midi a me battre avec
Donc si j'ai bien comprit le principe je met les paramatres dans la pile via PUSH puis j'appelle la procédure avec CALL.
Seul problème heuu je PUSH quoi dans la pile ? et je CALL comment ?

D'apres mon amis google il faut jouer avec le registre qui contient les paramètres de la fonction ExecuteFunction et qui semble etre ESP et la je coince vraiment car a par faire des accès illégaux dans la mémoire je n'arrive a rien.

Si un érudit de l'asm pouvait m'apporter quelques lumières voir une ampoule de 500wats au passage j'en serait ravit.

pour info ma structure Function

Code : Tout sélectionner

Structure Function
  *ptr.i
  *param.i
  NbrParam.l
  Name.s
  RetourType.l
EndStructure
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

déjà, tu eux remplacer pow(x, 2) par 'x * x' qui est bien plus rapide
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

Message par cha0s »

Bien sur c'était juste un exemple c'est a l'utilisateur d'optimiser ses formules ! *retourne se battre avec les registres*
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Je pompe mes infos de PB dans le fichier fait par Fred qui se situe dans le dossier PureBasic \SDK, le fichier est un fichier texte en anglais qui se nomme Readme.txt

Il faut que tu le lises car il est plein d'infos (et en particulier les registres à sauvegarder)

La gestion des floattant/double utilise le registre STO

Voici ce que je sais pour la version 32 bits, pour les 64 il faut que tu lises un post de Fred sur le forum anglais qui explique comment calculer les empilemets.

Pour ta procedure en 32 bits

Code : Tout sélectionner

Procedure.d ExecuteFunction(*this.Function, *param)
  ProcedureReturn CallFunctionFast(*this\ptr, blablabla)
EndProcedure
tu mets sur la pile (tu empiles) en commençant par le dernier paramètre soit param qui est un pointeur c''est donc une valeur sur 32 bits

Ensuite tu empiles le premier paramètre (*This) qui est un pointeur, idem c'est une valeur sur 32 bits

Pour accéder aux différents éléments de ta structure, tu charges dans un registre ton pointeur et tu lui ajoutes l'offset correspondant (c'est pour chaque élément la valeur retournée par les commande PB offsetOf().

Le code ASM devient (créé par mon générateur de squelette ASM pour PB qui est en cours de développement), je n'ai pas fait de sauvegarde des registres PB , alors à toi de savoir ce que tu dois sauvegarder.

Pour retourner un double, utilises le registre STO, je te conseille à partir de ton fichier PB de ta procedure, de créer le fichier asm avec le compilateur PB et de regarder comment Fred a fait, c'est en général comme ça que j'avance.

Dans le code qui suit, tu accèdes aux paramètres avec le registre esp alors prudence pour éviter les crash, PB fait de même.

Code : Tout sélectionner

format MS COFF
public PB_ExecuteFunction

; -------------------------------------------;
; Paramètres d'entrée
; -------------------------------------------;

; This.l
This   equ   dword esp+4

; Param.l
Param    equ   dword esp+8

; -------------------------------------------;
; Section code ;
; -------------------------------------------;

section '.text' code readable executable

PB_ExecuteFunction:


; **************************************************
; Mettez votre code asm perso après cette ligne












; fin de la zone de votre code asm perso 
; **************************************************

; -------------------------------------------;
; un nombre flottant ou double doit être
; retourné avec ST0
; -------------------------------------------;

_Retour:
 RET 8
cha0s
Messages : 681
Inscription : sam. 05/mars/2005 16:09

Message par cha0s »

Merci pour les infos, j'ai réussi a appeler des fonctions simple directement en ASM. Mon problème va maintenant être de passer les paramètres dans la pile sachant que leurs nombres change selon la fonction ce qui implique des test sans changer l'état de la pile.
Répondre