Page 1 sur 1

CallFunctionFast version ASM

Publié : ven. 03/oct./2008 22:43
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

Publié : sam. 04/oct./2008 12:39
par Le Soldat Inconnu
déjà, tu eux remplacer pow(x, 2) par 'x * x' qui est bien plus rapide

Publié : sam. 04/oct./2008 14:10
par cha0s
Bien sur c'était juste un exemple c'est a l'utilisateur d'optimiser ses formules ! *retourne se battre avec les registres*

Publié : sam. 04/oct./2008 15:56
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

Publié : dim. 05/oct./2008 21:00
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.