Delphi (6) + ASM en ligne ... Problème !!!

Signaler
Messages postés
7
Date d'inscription
jeudi 24 juillet 2003
Statut
Membre
Dernière intervention
20 septembre 2004
-
Messages postés
7
Date d'inscription
jeudi 24 juillet 2003
Statut
Membre
Dernière intervention
20 septembre 2004
-
Voici un problème concernant un programme tres simple utilisant l'Assembleur en ligne sous
Delphi 6.
Dans l'exemple n°1, "gogo" et "toto" sont incrémentés a chaque click, pas de problème !
dans l'exemple n°2, "gogo" est toujours incrémenté, mais "toto" ne l'est PLUS !!!
Pourquoi ????
Ce problème est plus compliqué qu'il n'y parrait. Les réponses simples ne suffiront pas ... dommage ! hi
Je passe l'adresse de "toto" a la procédure "Robby" et dans cette procédure, j'utilise bien entendu l'adressage indexé pour atteindre "toto" ... avec "indic" son adresse.
Allez voir le code résultat généré par le compilateur dans ces deux cas ... vous allez comprendre qu'il y a un problème. Dans le 2eme ca, le compilateur génère un code dans lequel l'adressage indexé ne fonctionne plus ... aucune erreur a la compilation, mais le programme ne fonctionne plus ! toto n'est plus incrémenté !!! Celui qui connait la syntaxe pour retrouver un code compilé correcte dans l'exemple 2, ... c'est un AS ! Je ne parle pas de "transformer" ... pour "y arriver quand meme" ... mais de conserver le prog . comme il est et de le faire fonctionner ... car ... ce prog. (exemple 2) est tout a fait correcte ! je prétend qu'il y a ici un réel soucis au niveau du compilateur ! amicalement a tous et toutes ...

------------------- Exemple n°1 -------------------------------------

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure buttonclick1(Sender: TObject);
procedure FormCreate (Sender: TObject);
end;

var
Form1: TForm1;
toto : byte ;
gogo : byte ;

implementation

{$R *.dfm}

{==================================================== Procédure Robby n°1 }
procedure robby (var indic:byte);

asm
inc byte [indic]
end;
{==================================================== Robby n°1 "end" }

procedure TForm1.FormCreate(Sender: TObject);
begin
toto := 0;
gogo := 0;
end;

procedure TForm1.buttonclick1(Sender: TObject);
begin
robby(toto);
gogo := gogo + 1 ;
Edit1.Text := IntToStr(toto)+' '+IntToStr(gogo);
end;

end.

----------- Exemple n° 2 ---------------------------------------------------

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure buttonclick1(Sender: TObject);
procedure FormCreate (Sender: TObject);
end;

var
Form1: TForm1;
toto : byte ;
gogo : byte ;

implementation

{$R *.dfm}

{==================================================== Procédure Robby n°2 }
procedure robby (var indic:byte);

begin
gogo := gogo + 1 ;
asm
inc byte [indic]
end;
end;
{==================================================== Robby n°2 "end" }
procedure TForm1.FormCreate(Sender: TObject);
begin
toto := 0;
gogo := 0;
end;

procedure TForm1.buttonclick1(Sender: TObject);
begin
robby(toto);
Edit1.Text := IntToStr(toto)+' '+IntToStr(gogo);
end;

end.

5 réponses

Messages postés
540
Date d'inscription
dimanche 23 mars 2003
Statut
Membre
Dernière intervention
5 octobre 2007
1
C'est parce que l'argument de la procédure robby est un passé par référence, ton prog incrément donc l'octet de poids faible d'une adresse (un pointeur). Car en réalité l'agument indic est un pointeur et quand tu y fais une affectation en fait le compilateur fait une indirection.

Tu dois faire:
procedure robby (var indic:byte);
begin
gogo := gogo + 1 ;
asm
mov eax, indic
inc byte [eax]
end;
end;


Core Breaker :)
Messages postés
540
Date d'inscription
dimanche 23 mars 2003
Statut
Membre
Dernière intervention
5 octobre 2007
1
Pardon je me suis trompé dans le code oubli mon message précédent.

C'est parce que l'argument de la procédure robby est un passé par référence, ton prog incrément donc l'octet de poids faible d'une adresse (un pointeur). Car en réalité l'agument indic est un pointeur et quand tu y fais une affectation en fait le compilateur fait une indirection.

Tu dois faire:
procedure robby (var indic:byte);
begin
gogo := gogo + 1 ;
asm
mov eax, [indic]
inc byte [eax]
end;
end;


Core Breaker :)
Messages postés
7
Date d'inscription
jeudi 24 juillet 2003
Statut
Membre
Dernière intervention
20 septembre 2004

Merci pour ta réponse !
oui, ok ! mais alors pourquoi cette procédure Robby fonctionne t elle quand il n'y a pas "gogo" dedans.
procédure Robby (var indic:byte);
ASM
   inc [indic]
end;

Quand il n'y a pas la ligne avec "gogo" en plus, ca fonctionne sans problème ! toto est bien incrémenté au retour. C'est quand je place "gogo" avec un "begin-end;" en plus que ca ne fonctionne plus. Essaye, tu vas voir ! avec uniquement le code ci dessus ... nickel ... et si je place "gogo" en plus dans la procédure "robby" ... inc[indic] qui faisait bien son "travail" ne fonctionne plus ??? merci a toi de m'aider dans ce problème. Ici, ta réponse et ton avis m'intéresserait beaucoup !
Messages postés
540
Date d'inscription
dimanche 23 mars 2003
Statut
Membre
Dernière intervention
5 octobre 2007
1
Je n'ai pas Delphi donc je ne peux pas tester.
Dis moi au moi au moins si le code de la procédure que je t'ai passé fonctionne.

A mon avis l'assembleur en ligne doit avoir un petit défaut.
Ca ne chage rien de toute façon, l'argument est toujours une adresse car c'est un passage par référence. Mais l'agument est traduit différemment suivant que ta procédure est en assembleur pur (sans begin/end) ou en Pascal avec de l'assembleur (begin/end avec asm/end)

L'assembleur en ligne doit alors réagir différemment car il n'a pas du code Pascal, et donc le compilateur Pascal ne doit pas sans doute pas rajouter son grain de sel, pour interférer avec l'assembleur en ligne.

Donc si c'est en assembleur pur, l'arguement dans le code assembleur est traduit directement comme une adresse. De ce fait tu n'a plus besoin de résupérer l'adresse de l'agument en faisant:
mov eax, [indic]


Core Breaker :)
Messages postés
7
Date d'inscription
jeudi 24 juillet 2003
Statut
Membre
Dernière intervention
20 septembre 2004

Oui, ta procédure fonctionne. Je suis allé voir de plus pres les codes compilés. Pour bien savoir de quoi on parle voici , premier cas: toto seul avec "inc[indic] ... deuxième cas : gogo en plus avec un begin-end en plus... ok ?
bon ! ... on peut mettre la clause "register" qui force le compilateur a passer ses "infos" via les registres, mais en l'absence de clause, c'est "register" par défaut !
Premier cas : l'adresse de toto est passée a la procédure dans eax, on peut alors faire "inc[indic], et au retout toto est bien incrémenté. pas de problème, ca fonctionne !
Deuxième cas : l'adresse de toto est tjs envoyée a la procédure via eax, MAIS une fois dans la procédure on a "mov [bp+8],eax !!! et ensuite indic ne désigne plus eax, mais bp+8. Si j'écris (dans le second cas) "inc[indic]" et que je vais voir le code compilé, je n'ai plus "inc[eax] mais inc[bp+8] !!! et c'est la ou est le problème . Je ne sais plus atteindre toto directement ! Je trouve que ce n'est pas normal. Oui, je pense aussi qu'il y a un petit soucis coté assembleur en ligne sous Delphi (ou alors y'a des trucs qu'on sait pas, je cherche tjs !). Le programme au départ fonctionne (toto seul) et parceque j'introduis gogo, ca va plus .. le compilateur compile autrement et ca plante ! c'est pas normal ! ... voila. tout grand merci ! si un jour tu apprends un truc en plus la dessus, fait moi signe stp ! e-mail: toto8966@hotmail.com ... bye !