10.11.2015, 20:03
(
Последний раз редактировалось Dutheil; 10.11.2015 в 20:34.
)
[CENTER][SIZE="6"][COLOR="RoyalBlue"]L'assembleur (#emit) - Partie 3[/COLOR][/SIZE]
Suite du tutoriel sur la maоtrise de l'assembleur en Pawn avec la directive #emit.
Nous verrons les diffйrentes adresses et comment les obtenir.[/CENTER]
[SIZE="4"]Initiation:[/SIZE]
Petite dйfinition de Wikipйdia pour commencer :
Зa nous parle donc d'adresses et de mйmoires. Comme je vous l'ai dit dans les premiers tutoriels, vous avez diffйrents registres, certains sont considйrйs comme des mйmoires temporaires, leur valeur change souvent durant l'exйcution du programme, d'autres ne changent pas.
Nous saurons dans ce tutoriel quels registres stockent les adresses ou pointeurs d'adresses importantes et surtout vers quoi ces adresses pointent.
[SIZE="3"]Adresse locale:[/SIZE][INDENT]Si vous avez dйjа compilй votre code avec la sortie '-a', vous avez donc pu remarquer dans votre fichier .asm, qu'а la ligne de votre variable, s'y joint une valeur hexadйcimale.
C'est en rйalitй une adresse locale.
Il y a deux types d'adresses locales :
- L'adresse locale de variable locale -> est toujours une valeur nйgative.
- L'adresse locale de paramиtres d'une fonction -> est toujours une valeur positive.
Prenons par exemple ce code :
Nous avons donc deux variables locales dйclarйes dans la fonction "main", nommйes "a" et "b", qui sont passйs en arguments dans la fonction "func".
Notre fonction "func" contient deux paramиtres, "c" et "d".
Derniиre nos "a" et "b" nous aurons donc 2 adresses locales nйgatives car ce sont des variables locales.
Et derriиre nos "c" et "d" nous aurons donc 2 adresses locales positives car ce sont des paramиtres de fonction.
Compilons en sortie '-a' et regardons de plus prиs nos adresses :
J'ai volontairement laissй les "proc" pour que vous vous y retrouviez.
En utilisant ce site http://www.mathsisfun.com/binary-decimal...erter.html, vous pouvez convertir de l’hexadйcimale vers du dйcimale en respectant le type signed 32 bits.
Je n'ai pas besoin d'utiliser ce site pour vous dire que l'adresse locale de la variable :
a = -4
b = -8
c = 12
d = 16
Pourquoi ? Une simple habitude que vous devrez avoir.
Comme je vous l'ai dit, vous pouvez constater des valeurs positives et nйgatives pour nos adresses.
Ce qu'il faut donc savoir, c'est que l'adresse locale de la premiиre variable locale dans votre fonction sera -4.
Pour les suivantes, vous n'aurez plus qu'а soustraire par 4. (-4, -8, -12, -16, -20...)
Pour les adresses locales dans nos fonctions, c'est diffйrent, nous avons nos valeurs positives qui commencent а 12.
Nous verrons dans d'autres tutoriels ce que renferme les valeurs 0, 4 et 8 de nos fonctions.
Donc l'adresse locale de n'autre premier paramиtre de fonction sera 12, pour la suite il faut y ajouter 4 а chaque fois. (12, 16, 20 24, 28, 32...).
Il y a une mйthode pour charger l'adresse locale d'une variable ou d'un paramиtre de fonction dans un registre temporaire (primaire ou alternй si vous avez oubliй).
Pour зa nous utiliserons le p-code CONST.pri/alt.
Ce p-code permet de charger une constante dans un registre temporaire.
Ici je charge la valeur 5 dans le registre temporaire.
Mais les adresses locales sont considйrйes comme des constantes, on peut donc passer en paramиtre du p-code une variable.
Si vous avez compris, vous saurez que зa nous affichera : -4 | 0xFFFFFFFC.
Si vous ne comprenez pas, n'hйsitez pas а relire cette partie, ne cherchez pas а comprendre а quoi зa sert pour le moment, retenez juste зa et pensez а essayer le p-code CONST dans d'autres cas.[/INDENT]
[SIZE="3"]Adresse relative:[/SIZE][INDENT]Si vous vous souvenez du Frame Pointer, vous pouvez continuer de lire, sinon, relisez le tutoriel prйcйdent.
L'adresse relative permet tout simplement de pointer vers une autre adresse pour rйcupйrer la valeur d'une variable ("Adresse globale" appelйe aussi "adresse de la valeur").
Pour obtenir l'adresse relative d'une variable, il y a 2 solutions avec des p-codes, je vais vous montrer la plus "compliquйe" pour que vous compreniez la plus simple.
L'adresse relative d'une variable est composйe du frame pointer + l'adresse locale de la variable.
En 4 йtapes :
On charge le Frame Pointer dans le registre primaire, зa vous savez pas encore le faire, mais зa vient.
On charge l'adresse locale d'une variable locale dans le registre alternй, vous savez faire.
On additionne le registre alternй avec le registre primaire, vous savez faire.
On stocke la valeur du registre primaire dans une autre variable locale, vous savez faire.
Donc vous savez а 75% faire tout зa, il faut donc que je vous apprenne а charger dans le registre primaire le Frame Pointer.
Le p-code pour зa est LCTRL, il permet de charger dans le registre primaire des mйmoires indiquйes en paramиtre.
Les mйmoires sont numйrotйes de 0 а 6.
Vous savez maintenant charger le FRM dans le registre primaire.
Tenter de stocker l'adresse relative de la variable "a" dans le variable "relative_address" :
A tout de suite !
Donc, si vous кtes lа c'est que vous avez tentй (ou pas) de faire le code demandй et que vous voulez la suite de ce tutoriel.
Voici le code correct :
Mais je peux vous dire qu'il y a moyen de simplifier ce code ici :
Grвce au p-code : ADD.C
Il permet de charger une constante et l'additionner avec le registre primaire.
Pfiou un p-code en moins !
Mais si je vous dis que l'on peut encore diminuer d'un p-code !
Oui, souvenez-vous je vous parlais de la mйthode simple, elle fonctionne simplement en utilisant le p-code ADDR.pri/alt qui charge l'adresse relative d'une variable dans le registre indiquй.
En pratique :
Et voilа, vous savez rйcupйrer l'adresse relative d'une variable et vous comprenez dans quel cas vous pouvez utiliser l'adresse locale d'une variable.[/INDENT]
[SIZE="3"]Adresse globale:[/SIZE][INDENT]L'adresse globale est l'adresse а laquelle est stockйe vйritablement la valeur dans la [URL="https://fr.wikipedia.org/wiki/M%C3%A9moire_vive"]mйmoire vive[/URL].
Prenons une variable nommйe "a" stockant la valeur 5533.
L'adresse globale ayant la valeur 5533 peut-кtre obtenue а partir de l'adresse relative de la variable "a" en l'additionnant а un segment. Mais lequel ?
Ca va vous choquer si je vous dis que c'est le segment DATA ? Et pourtant si.
Je vous expliquerai dans un autre tutoriel pourquoi.
Contentons-nous de la rйcupйrer et la stocker dans une variable.
Je vous redonne ceci :
Vous кtes normalement capable de me rйsoudre ce code :
A tout de suite :mrgreen:
Ah vous кtes dйjа lа ? Vous avez fini ? Trиs bien, comparons nos codes ! :
Vous avez bon ? Tant mieux, vous кtes sur la bonne voie de l'apprentissage de l'assembleur.
Dans le cas contraire, n'hйsitez pas а relire les tutoriels et posez vos questions.
Pour l'utilisation de l'adresse globale, vous comprendrez dans d'autres tutoriels pourquoi je vous ai appris а la rйcupйrer.[/INDENT]
[CENTER]____________________________________________________
Tutoriel fini !
Si vous avez une question n'hйsitez pas, postez а la suite de ce sujet.
Allez bisous ![/CENTER]
Suite du tutoriel sur la maоtrise de l'assembleur en Pawn avec la directive #emit.
Nous verrons les diffйrentes adresses et comment les obtenir.[/CENTER]
[SIZE="4"]Initiation:[/SIZE]
Petite dйfinition de Wikipйdia pour commencer :
Wikipйdia Wrote:L’adressage mйmoire est, en йlectronique et informatique, la faзon dont sont accйdйes des donnйes stockйes en mйmoire. Une adresse mйmoire est un nombre entier naturel (rarement une autre sorte d'identifiant) qui dйsigne une zone particuliиre de la mйmoire, ou juste le dйbut d'une zone. Le plus souvent, une donnйe peut кtre lue ou йcrite. La mйmoire peut кtre temporaire (mйmoire vive) pour le travail ou au contraire durable (mйmoire non volatile) pour le stockage.
Зa nous parle donc d'adresses et de mйmoires. Comme je vous l'ai dit dans les premiers tutoriels, vous avez diffйrents registres, certains sont considйrйs comme des mйmoires temporaires, leur valeur change souvent durant l'exйcution du programme, d'autres ne changent pas.
Nous saurons dans ce tutoriel quels registres stockent les adresses ou pointeurs d'adresses importantes et surtout vers quoi ces adresses pointent.
[SIZE="3"]Adresse locale:[/SIZE][INDENT]Si vous avez dйjа compilй votre code avec la sortie '-a', vous avez donc pu remarquer dans votre fichier .asm, qu'а la ligne de votre variable, s'y joint une valeur hexadйcimale.
C'est en rйalitй une adresse locale.
Il y a deux types d'adresses locales :
- L'adresse locale de variable locale -> est toujours une valeur nйgative.
- L'adresse locale de paramиtres d'une fonction -> est toujours une valeur positive.
Prenons par exemple ce code :
PHP Code:
#include "a_samp"
main()
{
new
a,
b;
func(a, b);
}
func(c, d)
{
#pragma unused c, d
}
Nous avons donc deux variables locales dйclarйes dans la fonction "main", nommйes "a" et "b", qui sont passйs en arguments dans la fonction "func".
Notre fonction "func" contient deux paramиtres, "c" et "d".
Derniиre nos "a" et "b" nous aurons donc 2 adresses locales nйgatives car ce sont des variables locales.
Et derriиre nos "c" et "d" nous aurons donc 2 adresses locales positives car ce sont des paramиtres de fonction.
Compilons en sortie '-a' et regardons de plus prиs nos adresses :
PHP Code:
proc ; main
;$lcl a fffffffc
;$lcl b fffffff8
proc ; func
;$lcl d 10
;$lcl c c
J'ai volontairement laissй les "proc" pour que vous vous y retrouviez.
En utilisant ce site http://www.mathsisfun.com/binary-decimal...erter.html, vous pouvez convertir de l’hexadйcimale vers du dйcimale en respectant le type signed 32 bits.
Je n'ai pas besoin d'utiliser ce site pour vous dire que l'adresse locale de la variable :
a = -4
b = -8
c = 12
d = 16
Pourquoi ? Une simple habitude que vous devrez avoir.
Comme je vous l'ai dit, vous pouvez constater des valeurs positives et nйgatives pour nos adresses.
Ce qu'il faut donc savoir, c'est que l'adresse locale de la premiиre variable locale dans votre fonction sera -4.
Pour les suivantes, vous n'aurez plus qu'а soustraire par 4. (-4, -8, -12, -16, -20...)
Pour les adresses locales dans nos fonctions, c'est diffйrent, nous avons nos valeurs positives qui commencent а 12.
Nous verrons dans d'autres tutoriels ce que renferme les valeurs 0, 4 et 8 de nos fonctions.
Donc l'adresse locale de n'autre premier paramиtre de fonction sera 12, pour la suite il faut y ajouter 4 а chaque fois. (12, 16, 20 24, 28, 32...).
Il y a une mйthode pour charger l'adresse locale d'une variable ou d'un paramиtre de fonction dans un registre temporaire (primaire ou alternй si vous avez oubliй).
Pour зa nous utiliserons le p-code CONST.pri/alt.
Ce p-code permet de charger une constante dans un registre temporaire.
PHP Code:
#emit CONST.pri 5
Mais les adresses locales sont considйrйes comme des constantes, on peut donc passer en paramиtre du p-code une variable.
PHP Code:
#include "a_samp"
main()
{
new
a;
#emit CONST.pri a
#emit STOR.S.pri a
printf("%d | 0x%x", a, a);
}
Si vous avez compris, vous saurez que зa nous affichera : -4 | 0xFFFFFFFC.
Si vous ne comprenez pas, n'hйsitez pas а relire cette partie, ne cherchez pas а comprendre а quoi зa sert pour le moment, retenez juste зa et pensez а essayer le p-code CONST dans d'autres cas.[/INDENT]
[SIZE="3"]Adresse relative:[/SIZE][INDENT]Si vous vous souvenez du Frame Pointer, vous pouvez continuer de lire, sinon, relisez le tutoriel prйcйdent.
L'adresse relative permet tout simplement de pointer vers une autre adresse pour rйcupйrer la valeur d'une variable ("Adresse globale" appelйe aussi "adresse de la valeur").
Pour obtenir l'adresse relative d'une variable, il y a 2 solutions avec des p-codes, je vais vous montrer la plus "compliquйe" pour que vous compreniez la plus simple.
L'adresse relative d'une variable est composйe du frame pointer + l'adresse locale de la variable.
En 4 йtapes :
On charge le Frame Pointer dans le registre primaire, зa vous savez pas encore le faire, mais зa vient.
On charge l'adresse locale d'une variable locale dans le registre alternй, vous savez faire.
On additionne le registre alternй avec le registre primaire, vous savez faire.
On stocke la valeur du registre primaire dans une autre variable locale, vous savez faire.
Donc vous savez а 75% faire tout зa, il faut donc que je vous apprenne а charger dans le registre primaire le Frame Pointer.
Le p-code pour зa est LCTRL, il permet de charger dans le registre primaire des mйmoires indiquйes en paramиtre.
Les mйmoires sont numйrotйes de 0 а 6.
Code:
0 -> Le segment CODE
1 -> Le segment DATA
2 -> Le Heap
3 -> Le Stack Top
4 -> Le Stack
5 -> Le Frame Pointer
6 -> Le CIP (Code Instruction Pointer pour ceux qui auraient oubliйs)
Vous savez maintenant charger le FRM dans le registre primaire.
Tenter de stocker l'adresse relative de la variable "a" dans le variable "relative_address" :
PHP Code:
#include "a_samp"
main()
{
new
a,
relative_address;
printf("%d | 0x%x", relative_address, relative_address);
}
A tout de suite !
Donc, si vous кtes lа c'est que vous avez tentй (ou pas) de faire le code demandй et que vous voulez la suite de ce tutoriel.
Voici le code correct :
PHP Code:
#include "a_samp"
main()
{
new
a,
relative_address;
#emit LCTRL 5
#emit CONST.alt a
#emit ADD
#emit STOR.S.pri relative_address
printf("%d | 0x%x", relative_address, relative_address);
}
Mais je peux vous dire qu'il y a moyen de simplifier ce code ici :
PHP Code:
#emit CONST.alt a
#emit ADD
Il permet de charger une constante et l'additionner avec le registre primaire.
PHP Code:
#include "a_samp"
main()
{
new
a,
relative_address;
#emit LCTRL 5
#emit ADD.C a
#emit STOR.S.pri relative_address
printf("%d | 0x%x", relative_address, relative_address);
}
Pfiou un p-code en moins !
Mais si je vous dis que l'on peut encore diminuer d'un p-code !
Oui, souvenez-vous je vous parlais de la mйthode simple, elle fonctionne simplement en utilisant le p-code ADDR.pri/alt qui charge l'adresse relative d'une variable dans le registre indiquй.
En pratique :
PHP Code:
#include "a_samp"
main()
{
new
a,
relative_address;
#emit ADDR.pri a
#emit STOR.S.pri relative_address
printf("%d | 0x%x", relative_address, relative_address);
}
Et voilа, vous savez rйcupйrer l'adresse relative d'une variable et vous comprenez dans quel cas vous pouvez utiliser l'adresse locale d'une variable.[/INDENT]
[SIZE="3"]Adresse globale:[/SIZE][INDENT]L'adresse globale est l'adresse а laquelle est stockйe vйritablement la valeur dans la [URL="https://fr.wikipedia.org/wiki/M%C3%A9moire_vive"]mйmoire vive[/URL].
Prenons une variable nommйe "a" stockant la valeur 5533.
L'adresse globale ayant la valeur 5533 peut-кtre obtenue а partir de l'adresse relative de la variable "a" en l'additionnant а un segment. Mais lequel ?
Ca va vous choquer si je vous dis que c'est le segment DATA ? Et pourtant si.
Je vous expliquerai dans un autre tutoriel pourquoi.
Contentons-nous de la rйcupйrer et la stocker dans une variable.
Je vous redonne ceci :
Code:
0 -> Le segment CODE
1 -> Le segment DATA
2 -> Le Heap
3 -> Le Stack Top
4 -> Le Stack
5 -> Le Frame Pointer
6 -> Le CIP (Code Instruction Pointer pour ceux qui auraient oubliйs)
Vous кtes normalement capable de me rйsoudre ce code :
PHP Code:
#include "a_samp"
main()
{
new
a,
global_address;
printf("%d | 0x%x", global_address, global_address);
}
A tout de suite :mrgreen:
Ah vous кtes dйjа lа ? Vous avez fini ? Trиs bien, comparons nos codes ! :
PHP Code:
#include "a_samp"
main()
{
new
a,
global_address;
#emit LCTRL 1
#emit ADDR.alt a
#emit ADD
#emit STOR.S.pri global_address
printf("%d | 0x%x", global_address, global_address);
}
Vous avez bon ? Tant mieux, vous кtes sur la bonne voie de l'apprentissage de l'assembleur.
Dans le cas contraire, n'hйsitez pas а relire les tutoriels et posez vos questions.
Pour l'utilisation de l'adresse globale, vous comprendrez dans d'autres tutoriels pourquoi je vous ai appris а la rйcupйrer.[/INDENT]
[CENTER]____________________________________________________
Tutoriel fini !
Si vous avez une question n'hйsitez pas, postez а la suite de ce sujet.
Allez bisous ![/CENTER]