28.10.2015, 00:15
[CENTER][SIZE="6"][COLOR="RoyalBlue"]L'assembleur (#emit) - Partie 2[/COLOR][/SIZE]
Suite du tutoriel sur la maоtrise de l'assembleur en Pawn avec la directive #emit.
Nous verrons ce qu'est le FRM, le CIP et nous nous focaliserons de plus prкt au DATA.[/CENTER]
[SIZE="4"]Initiation:[/SIZE]
On commence avec un schйma !
Il y a surement quelques termes dans ce schйma qui vous parlent, notamment le "stack".
Derriиre des valeurs stockйes dans le stack, se cachent des adresses. Elles sont pointйes par le FRM (Frame Pointer). L'abstract machine, ne peut pas rйcupйrer l'adresse а partir d'une valeur, c'est pourquoi le Frame Pointer est rйguliиrement utilisй, par exemple quand vous pushez des valeurs dans vos paramиtres, par "pusher" qui se traduit par "pousser" je parle de passer des valeurs en paramиtres de fonctions tout simplement.
Retenez bien ce terme "push".
Le CIP (Code Instruction Pointer) stocke tout simplement la valeur ou l'adresse qui sont passйes en paramиtre avec un p-code (mnйmonique pour les nostalgiques, boum une rime).
[SIZE="3"]Data, static, valeur, load:[/SIZE][INDENT]C'est une partie importante de l'abstract machine, donc soyez attentifs.
Je vous disais dans la partie 1 que :
Le data ne s'arrкte pas lа. Ce qu'il faut savoir, c'est que le data stocke aussi les valeurs de vos variables statiques.
Donc, LOAD.S.pri ne fonctionnera pas avec un offset (variable en paramиtre d'un p-code) statique, vous pouvez faire le test :
Cela vous affichera 0.
Mais comment faire ?
Avant toute chose, je n'ai pas expliquй concrиtement ce que fait le p-code LOAD.S.pri vous pensez qu'il permet de charger une valeur а partir d'une variable en offset, mais pas vraiment.
C'est lа que viens l'utilisation de notre FRM et notre DATA, allez cadeau voici un code en C (amx.c) :
Si on retire les cast (type des variables) et que je remplace la macro GETPARAM, зa nous donne ceci :
Je traduis donc :
- On rйcupиre la valeur а l'adresse de "cip", on stocke la valeur dans "offset" et on incrйmente "cip", donc c'est la variable qu'on aura passй en paramиtre au p-code.
- On additionne le pointeur "data" aux variables "frm" et "offs", le rйsultat nous donnera l'adresse de la variable qu'on aura passй en paramиtre au p-code, on rйcupиre donc sa valeur а l'aide du caractиre * et on la stocke dans la variable "pri" qui est le registre primaire.
Pourquoi frm+offs ? Car c'est une base de l'adresse de la variable (rappelez-vous le FRM stocke seulement une adresse de variable et non sa valeur) et en y rajoutant le pointeur data, on obtient la valeur de l'adresse.
Pourquoi ajouter le data ? Vous comprendrez plus tard, mais sachez que vous entendrez toujours parler.
Ce p-code permet donc de rйcupйrer une valeur а partir de la variable, de la stocker dans le registre primaire.
La variable doit кtre locale et кtre situйe dans le stack, donc ne doit pas кtre statique.
Je vais quand mкme dйcortiquer encore un peu le p-code, juste son nom pas d'inquiйtude :
Ils se ressemblent, а quelques exceptions, certains commencent par LOAD, d'autres par STOR, certains comportent un S, d'autres non, certains comportent un pri, d'autres un alt.
Pour sauter vite fait un paragraphe, les p-codes finissant par .alt, sachez juste que c'est pour agir sur le registre alternй et que c'est similaire au registre primaire, ce n'est qu'un registre temporaire.
On reprend donc notre liste sans nos .alt :
Et bien tout simplement d'aller chercher une valeur dans le DATA sans passer par un autre segment.
Cela signifie qu'avec ces p-codes vous pourrez charger ou stocker des valeurs dans des variables statiques ou globales.
Voici un exemple :
[/INDENT]
[CENTER]____________________________________________________
Tutoriel fini !
Si vous avez une question n'hйsitez pas, postez а la suite de ce sujet.
Prochaine partie "зa va pousser".
Allez bisous ![/CENTER]
Suite du tutoriel sur la maоtrise de l'assembleur en Pawn avec la directive #emit.
Nous verrons ce qu'est le FRM, le CIP et nous nous focaliserons de plus prкt au DATA.[/CENTER]
[SIZE="4"]Initiation:[/SIZE]
On commence avec un schйma !
Il y a surement quelques termes dans ce schйma qui vous parlent, notamment le "stack".
Derriиre des valeurs stockйes dans le stack, se cachent des adresses. Elles sont pointйes par le FRM (Frame Pointer). L'abstract machine, ne peut pas rйcupйrer l'adresse а partir d'une valeur, c'est pourquoi le Frame Pointer est rйguliиrement utilisй, par exemple quand vous pushez des valeurs dans vos paramиtres, par "pusher" qui se traduit par "pousser" je parle de passer des valeurs en paramиtres de fonctions tout simplement.
Retenez bien ce terme "push".
Le CIP (Code Instruction Pointer) stocke tout simplement la valeur ou l'adresse qui sont passйes en paramиtre avec un p-code (mnйmonique pour les nostalgiques, boum une rime).
[SIZE="3"]Data, static, valeur, load:[/SIZE][INDENT]C'est une partie importante de l'abstract machine, donc soyez attentifs.
Je vous disais dans la partie 1 que :
Quote:Les variables en dehors des fonctions dites globales, sont stockйes dans le segment "data" (DAT).Mais pas seulement!
Le data ne s'arrкte pas lа. Ce qu'il faut savoir, c'est que le data stocke aussi les valeurs de vos variables statiques.
Donc, LOAD.S.pri ne fonctionnera pas avec un offset (variable en paramиtre d'un p-code) statique, vous pouvez faire le test :
PHP Code:
#include "a_samp"
main()
{
static
a = 5;
new
b;
#emit LOAD.S.pri a
#emit STOR.S.pri b
printf("%d", b);
}
Mais comment faire ?
Avant toute chose, je n'ai pas expliquй concrиtement ce que fait le p-code LOAD.S.pri vous pensez qu'il permet de charger une valeur а partir d'une variable en offset, mais pas vraiment.
C'est lа que viens l'utilisation de notre FRM et notre DATA, allez cadeau voici un code en C (amx.c) :
PHP Code:
case OP_LOAD_S_PRI:
GETPARAM(offs);
pri= * (cell *)(data+(int)frm+(int)offs);
Si on retire les cast (type des variables) et que je remplace la macro GETPARAM, зa nous donne ceci :
PHP Code:
case OP_LOAD_S_PRI:
offs = *cip++;
pri= * (data+frm+offs);
- On rйcupиre la valeur а l'adresse de "cip", on stocke la valeur dans "offset" et on incrйmente "cip", donc c'est la variable qu'on aura passй en paramиtre au p-code.
- On additionne le pointeur "data" aux variables "frm" et "offs", le rйsultat nous donnera l'adresse de la variable qu'on aura passй en paramиtre au p-code, on rйcupиre donc sa valeur а l'aide du caractиre * et on la stocke dans la variable "pri" qui est le registre primaire.
Pourquoi frm+offs ? Car c'est une base de l'adresse de la variable (rappelez-vous le FRM stocke seulement une adresse de variable et non sa valeur) et en y rajoutant le pointeur data, on obtient la valeur de l'adresse.
Pourquoi ajouter le data ? Vous comprendrez plus tard, mais sachez que vous entendrez toujours parler.
Ce p-code permet donc de rйcupйrer une valeur а partir de la variable, de la stocker dans le registre primaire.
La variable doit кtre locale et кtre situйe dans le stack, donc ne doit pas кtre statique.
Je vais quand mкme dйcortiquer encore un peu le p-code, juste son nom pas d'inquiйtude :
- LOAD -> Charge la valeur
- S -> se trouvant dans le stack
- pri -> et met dans le registre primaire
- LOAD.pri
- LOAD.alt
- LOAD.S.pri
- LOAD.S.alt
- STOR.pri
- STOR.alt
- STOR.S.pri
- STOR.S.alt
Ils se ressemblent, а quelques exceptions, certains commencent par LOAD, d'autres par STOR, certains comportent un S, d'autres non, certains comportent un pri, d'autres un alt.
Pour sauter vite fait un paragraphe, les p-codes finissant par .alt, sachez juste que c'est pour agir sur le registre alternй et que c'est similaire au registre primaire, ce n'est qu'un registre temporaire.
On reprend donc notre liste sans nos .alt :
- LOAD.pri
- LOAD.S.pri
- STOR.pri
- STOR.S.pri
- STOR -> Stocker la valeur
- S -> dans une variable situйe dans le stack
- pri -> du registre primaire
- LOAD.pri
- STOR.pri
Et bien tout simplement d'aller chercher une valeur dans le DATA sans passer par un autre segment.
Cela signifie qu'avec ces p-codes vous pourrez charger ou stocker des valeurs dans des variables statiques ou globales.
Voici un exemple :
PHP Code:
#include "a_samp"
new
a = 5;
main()
{
static
b;
#emit LOAD.pri a
#emit STOR.pri b
printf("%d", b);
}
[CENTER]____________________________________________________
Tutoriel fini !
Si vous avez une question n'hйsitez pas, postez а la suite de ce sujet.
Prochaine partie "зa va pousser".
Allez bisous ![/CENTER]