[Tutorial] L'assembleur (#emit) - Partie 2
#1

[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 !

[Image: n2VFXps.png]

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
        
5;

    new
        
b;

    
#emit LOAD.S.pri a
    #emit STOR.S.pri b

    
printf("%d"b);

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) :
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); 
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 :
  • LOAD -> Charge la valeur
  • S -> se trouvant dans le stack
  • pri -> et met dans le registre primaire
Voici donc des p-codes que vous sauriez reconnaоtre (ou presque) :
  • LOAD.pri
  • LOAD.alt
  • LOAD.S.pri
  • LOAD.S.alt
  • STOR.pri
  • STOR.alt
  • STOR.S.pri
  • STOR.S.alt
Regardez bien le noms de ces p-codes, oui je sais, il y en qui peuvent vous perturber.
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
Explication rapide pour STOR.S.pri :
  • STOR -> Stocker la valeur
  • S -> dans une variable situйe dans le stack
  • pri -> du registre primaire
On reprend notre liste en enlevant nos .S.pri puisque vous les comprenez logiquement :
  • LOAD.pri
  • STOR.pri
Argh, nous n'avons pas de 'S', qu'est-ce que зa peut bien vouloir dire ?
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
    
5;

main()
{
    static
        
b;

    
#emit LOAD.pri a
    #emit STOR.pri b

    
printf("%d"b);

[/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]
Reply
#2

Bon au lieu de dormir j'ai lu зa et maintenant je me boufe 2 aspirine olalalala la а mais pk dutheil :'( , Sinon Bonne suite de tutoriels malgrй que je n'ai pas totalement maоtriser la premiиre partie :p
Reply
#3

Comme je l'ai dit dans la premiиre partie, c'est pas dйdiй aux dйbutants et si tu ne sais ce que tu pourrais faire avec #emit, tu n'en as pas besoin!
Reply
#4

Merci beaucoup !
Reply
#5

Merci, intйressant.
Mais je pense que les cas d'utilisations ne seront pas excessif. Tout dйpend encore du contexte et du dйveloppement voulu ! ;)
Reply
#6

Si tu codes en PAWN (gamemode ou filterscript ou include) tu n'en as pas besoin, l'AMX sert a йtendre les possibilitйs du langage depuis lui mкme

Pas mal le tuto
Reply
#7

S4t3K;3603303 Wrote:Si tu codes en PAWN (gamemode ou filterscript ou include) tu n'en as pas besoin, l'AMX sert a йtendre les possibilitйs du langage depuis lui mкme

Pas mal le tuto

Autant faire un plugin quoi.
Reply
#8

Papawy;3603304 Wrote:Autant faire un plugin quoi.

Oui et non, car dans tous les cas, il faudrait savoir comment la mйmoire est gйrйe par l'abstract machine pour pouvoir interagir avec en C++ si tu souhaites la manipuler, donc autant le faire en Pawn.

S4t3K;3603303 Wrote:Si tu codes en PAWN (gamemode ou filterscript ou include) tu n'en as pas besoin, l'AMX sert a йtendre les possibilitйs du langage depuis lui mкme
Exact, mais quand tu dis qu'on n'en a pas besoin pour une include, зa dйpend si dans ce cas tu veux йtendre le Pawn.
Prenons par exemple y_amx, y_va ou y_inline, elles sont а 80% faites en assembleur.

S4t3K;3603303 Wrote:Pas mal le tuto
Merci bb
Reply
#9

" j'ai dis ca pour йviter les questions du type "Comment je crйe une voiture avec #emit ?". La rйponse c'est tu ne le fais pas." doit y avoir une vingtaine de personnes sur ce forum qui savent faire des trucs concrets avec #emit, sur les 5000 connectйs par jour
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)