Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Portabilité du *concept* des fonctions "naked"

40 réponses
Avatar
Patrick Brunet
Bonjour.

Je voudrais faire un tour des différentes plates-formes sous C pour savoir
s'il y existe des équivalents d'une extension Microsoft, les fonctions
"naked".

Une fonction dotée de cet attribut est appelée extérieurement selon la
convention dite cdecl (le code appelant empile les arguments puis la partie
externe de la stackframe, et fait le ménage au retour), mais par contre
aucune stackframe n'est créée du côté interne.

Le but est de laisser le programmeur faire ce qu'il veut ex-nihilo,
généralement avec de l'assembleur inline. C'est très utile dans certains
contextes (drivers par exemple).

Pour ma part, j'y vois une possibilité d'implémentation de la technique
d'enfilage de pseudo-instructions, avec par rapport au goto l'avantage de la
récursivité.

Merci de me dire si vous connaissez des concepts similaires sur les
principales plates-formes (système + compilo) autres que (Windows + Cµsoft).

Merci beaucoup de votre aide.
Cordialement,

Patrick Brunet

10 réponses

1 2 3 4
Avatar
Pierre Maurette
"Patrick Brunet" <Patrick.Brunet @ cned.fr> a écrit dans le message de news:
3f447692$0$6189$
Bonjour.

Je voudrais faire un tour des différentes plates-formes sous C pour savoir
s'il y existe des équivalents d'une extension Microsoft, les fonctions
"naked".

Une fonction dotée de cet attribut est appelée extérieurement selon la
convention dite cdecl (le code appelant empile les arguments puis la
partie

externe de la stackframe, et fait le ménage au retour), mais par contre
aucune stackframe n'est créée du côté interne.

Le but est de laisser le programmeur faire ce qu'il veut ex-nihilo,
généralement avec de l'assembleur inline. C'est très utile dans certains
contextes (drivers par exemple).

Pour ma part, j'y vois une possibilité d'implémentation de la technique
d'enfilage de pseudo-instructions, avec par rapport au goto l'avantage de
la

récursivité.

Merci de me dire si vous connaissez des concepts similaires sur les
principales plates-formes (système + compilo) autres que (Windows +
Cµsoft).

Bonjour,
En Delphi (= Pascal Objet) :

RetType MaFonction(Param1,...);assembler;
asm
...(code assembleur)
end;

(le mot-clé assembler est obsolète et donc facultatif)
Ne crée ni code de prologue, ni code d'épilogue. A la différence de :

RetType MaFonction(Param1,...)
begin
asm
...(code assembleur)
end; //asm
end;

Pour les autres compilos 'C', j'attends les réponses, le sujet m'intéresse
également. En fait, ce sont les deux méthodes que je connais pour faire des
fonction 100% assembleur. Pour C++ Builder, ou C++ 5.5, je n'en vois pas
d'autre que de faire un .asm, l'assembler et le lier. Alors, des suggestions
?

Bonne journée,

Pierre

Avatar
Jean-Marc
"Pierre Maurette" a écrit:
"Patrick Brunet" a écrit:


Bonjour,

En Delphi (= Pascal Objet) :

RetType MaFonction(Param1,...);assembler;
asm
...(code assembleur)
end;

(le mot-clé assembler est obsolète et donc facultatif)
Ne crée ni code de prologue, ni code d'épilogue. A la différence de
:


RetType MaFonction(Param1,...)
begin
asm
...(code assembleur)
end; file://asm
end;

Pour les autres compilos 'C', j'attends les réponses, le sujet
m'intéresse également.


Sous Gcc:

__asm__ volatile
{
... (code assembleur)
}


A
+
Jean-Marc

Avatar
Patrick Brunet
Bonjour.

Merci pour vos réponses, mais je tiens à préciser mon objectif:

- il ne s'agit pas de savoir comment introduire de l'assembleur inline (je
pense que la plupart des compilos C le permettent),
- je voudrais me limiter au C et le Pascal de Delphi me gêne un peu.

Mon objectif est de pratiquer en C pur (avec des portages par macros
dépendantes des compilos sans doute) la technique d'enfilage, qui est un
moyen très performant d'enchaîner les pseudo-instructions d'un algorithme
qui est composé au runtime (contexte d'intelligence artificielle).
Ca revient en fait à faire du goto calculé *au runtime*.
On peut obtenir quelque chose de semblable avec une itération sur un tableau
de pointeurs de fonctions à signatures identiques, mais donc je veux limiter
le coût des constructions de stackframes. Les p-instructions auront peu ou
pas d'argument, et travailleront sur un espace de mémoire commun (je sais
c'est pas propre, mais ici on n'est plus dans le code "source", le C sert de
code objet semi-portable).

Merci pour toute information dans ce sens.
Cordialement,

Patrick "Zener" Brunet
Avatar
Lavergne Thomas
Il est toujours possible d'include des fichier assembleurs compilés
séparement, mais c'est pas ce qu'il y a de plus pratique.

Si quelqu'un connait une façon de le faire proprement sous gcc je suis
interesser.

En Delphi (= Pascal Objet) :

RetType MaFonction(Param1,...);assembler;
asm
...(code assembleur)
end;

(le mot-clé assembler est obsolète et donc facultatif)
Ne crée ni code de prologue, ni code d'épilogue. A la différence de :


Faux. Delphi ne génere pas de prologue ni d'epilogue que lorsque le
nombre de parametre et de variable locales est nul, si tu ajoute des
parametre ou des variable locales tu obtien un prologue (qui depend de
ce que tu as ajouter) vas voir dans la doc sur les fonction asm pur tu
aura le detail.
Mais il vaudrai mieux continuer cette discution sur un froum delphi.

Avatar
Patrick Brunet
Bonjour.

"Arnaud Boulan" a écrit dans le message news:
bi2m6p$sc8$


Ca revient en fait à faire du goto calculé *au runtime*.


avec gcc on peut faire des gotos indirects:


En fait ça me paraît équivalent : je n'en suis pas encore à générer le code
des p-instructions lui-même au runtime, alors il s'agit bien de faire une
sélection au runtime parmi des sections de code définies au writetime.

Dans l'exemple ci-dessous, j'apprends quelque chose que j'ignorais : on
pourrait en C avoir une adresse pour un label ? C'est très bien pour mon
truc ! Esche c'est portable ?

Et au fait, il y a un truc qui me chiffonne : pourquoi un double & ?

Merci beaucoup pour les tuyaux...

cordialement,
PB


#include "stdio.h"
int main(int argc, char **argv)
{
void * table[] = {
&&label1,
&&label2,
&&label3,
&&label4
};

int i;
scanf("%d", &i);
if (i<1) i=1;
if (i>4) i=4;

/* goto indirect */
goto *table[i-1];

label1: printf("Je suis passé en 1n"); goto fin;
label2: printf("Je suis passé en 2n"); goto fin;
label3: printf("Je suis passé en 3n"); goto fin;
label4: printf("Je suis passé en 4n"); goto fin;

fin: return 1;
}


Bon, je sais, c'est pas du C standard... ;)

--
Arnaud



Avatar
Pierre Maurette
"Lavergne Thomas" a écrit dans le message de news:
bi3a3d$kiu$
Faux. Delphi ne génere pas de prologue ni d'epilogue que lorsque le
nombre de parametre et de variable locales est nul, si tu ajoute des
parametre ou des variable locales tu obtien un prologue (qui depend de
ce que tu as ajouter) vas voir dans la doc sur les fonction asm pur tu
aura le detail.
La doc est au mieux incomplète, au pire fausse. Comparez (testé sous Delphi

7) :
procedure test4(var a,b,c :integer);
begin
asm
inc dword ptr [a]
inc dword ptr [b]
inc dword ptr [c]
end;
end;

et :

procedure test4(var a,b,c :integer);
asm
inc dword ptr [a]
inc dword ptr [b]
inc dword ptr [c]
end;

Dans ce cas, tout se passe comme si c'était le begin qui générait le code de
prologue. Mais effectivement, peut-être ne faut-il pas généraliser.

Mais il vaudrai mieux continuer cette discution sur un froum delphi.
Nous sommes effectivement tout à fait HS.


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Patrick Brunet" <Patrick.Brunet @ cned.fr> wrote:

Je voudrais faire un tour des différentes plates-formes sous C pour
savoir s'il y existe des équivalents d'une extension Microsoft, les
fonctions "naked".


Rien de tel en C standard. Ce qui se rapproche le plus est peut peut être
l'inline (C99).

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Patrick Brunet
Bonjour.

"Emmanuel Delahaye" a écrit dans le message news:

In 'fr.comp.lang.c', "Patrick Brunet" <Patrick.Brunet @ cned.fr> wrote:

Je voudrais faire un tour des différentes plates-formes sous C pour
savoir s'il y existe des équivalents d'une extension Microsoft, les
fonctions "naked".


Rien de tel en C standard. Ce qui se rapproche le plus est peut peut être
l'inline (C99).



Merci, mais je précise (puisque j'ai dit *concept*) :

- il s'agit évidemment d'extensions spécifiques (en attendant que les
normalisateurs de C y trouvent un intérêt),
- les fonctions inline ne conviennent pas car - pour autant que le compilo
applique la directive - elles n'ont alors pas d'adresse et ne peuvent pas
servir pour faire de l'enfilage.

Arnaud Boulan a évoqué la possibilité (gcc) d'avoir l'adresse d'un simple
label. Je cherche actuellement à savoir si ça c'est normalisé. Ce serait
encore mieux pour moi que les naked (ou similaires).

Merci,

Cordialement,

PB


Avatar
Gabriel Dos Reis
"Patrick Brunet" <Patrick.Brunet @ cned.fr> writes:

| Arnaud Boulan a évoqué la possibilité (gcc) d'avoir l'adresse d'un simple
| label. Je cherche actuellement à savoir si ça c'est normalisé.

Prendre l'adresse d'un label est un des GNUismes que je voudrais voir
confiner au niveau -10. C'est une merde totale ce truc.

-- Gaby
Avatar
Richard Delorme

Bonjour.

Je voudrais faire un tour des différentes plates-formes sous C pour savoir
s'il y existe des équivalents d'une extension Microsoft, les fonctions
"naked".

Une fonction dotée de cet attribut est appelée extérieurement selon la
convention dite cdecl (le code appelant empile les arguments puis la
partie externe de la stackframe, et fait le ménage au retour), mais par
contre aucune stackframe n'est créée du côté interne.


A propos de naked, la doc de microsoft dit :
« For functions declared with the naked attribute, the compiler generates
code without prolog and epilog code. You can use this feature to write your
own prolog/epilog code using inline assembler code. Naked functions are
particularly useful in writing virtual device drivers. »

A propos de prolog et d'epilog, elle dit

prolog :
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers

epilog :
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function


l'effet de naked est donc plus ou moins équivalent à l'effet de l'option
-fomit-frame-pointer de gcc (sauf que cela affecte toutes les fonctions du
programmes).

--
Richard

1 2 3 4