OVH Cloud OVH Cloud

fonction en assembler dans BC++

5 réponses
Avatar
Sivaller
Je fais une fonction qui ressemble à ceci :
void _handlerdepipe()
{
_asm {
push ds
push bp
...
...
pop ds
pop bp
ret ;routine NEAR
}

Le compilateur me génére en supplément
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
//code de ma routine
push ds
push bp
...
...
pop ds
pop bp
ret ;routine NEAR
//
POP DI
POP SI
POP BP
RET

Ce qui est écrit en majuscule est la garniture inserer par le compilo.
Je souhaiterai que le compilateur ne me génére pas cette garniture (mov
bp,sp etc. ) sur ma fonction écrite en assembleur.
Comment faire ?

BORLAND C++ V4.02 (x86 16bits)

Merci

5 réponses

Avatar
Yann Renard
Sivaller wrote:

Je fais une fonction qui ressemble à ceci :
void _handlerdepipe()
{
_asm {
push ds
push bp
...
...
pop ds
pop bp
ret ;routine NEAR
}

Le compilateur me génére en supplément
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
//code de ma routine
push ds
push bp
...
...
pop ds
pop bp
ret ;routine NEAR
//
POP DI
POP SI
POP BP
RET

Ce qui est écrit en majuscule est la garniture inserer par le compilo.
Je souhaiterai que le compilateur ne me génére pas cette garniture (mov
bp,sp etc. ) sur ma fonction écrite en assembleur.
Comment faire ?

BORLAND C++ V4.02 (x86 16bits)

Merci


Ce n'est clairement pas une question concernant le C++ !!

Néanmoins, voici ce que je peux dire concernant ton problème : les
registres sauvegardés par le compilateur borland correspondent, si ma
mémoire est bonne, aux registres d'offset de code et de données, ainsi
que le pointeur de pile. Il les restaure à la sortie, en considérant
sans doute que c'est le minimum nécessaire pour garantir une bonne
continuation de l'execution du programme. Je pense que tu peux modifier
cela dans les options de compilations.

Un truc qui risque d'etre plus génant dans ce code :
_asm {
push ds
push bp

...

pop ds
pop bp
}

j'espere que tu es bien conscient que ds et bp sont inversés à la sortie
de ta fonction :) tu ne restaures donc pas correctement le contexte
d'execution.

Bon courage,

Yann Renard

Avatar
Pierre Maurette
"Sivaller" a écrit:
[...]
Je souhaiterai que le compilateur ne me génére pas cette garniture (mov
bp,sp etc. ) sur ma fonction écrite en assembleur.
Comment faire ?

BORLAND C++ V4.02 (x86 16bits)
Habituellement, cette fonctionalité non portable se cache sous le mot

"naked". Dans les versions actuelles du compilo Borland:

<C++Builder help>
Catégorie
Modificateurs, Extensions de C++Builder, Spécificateurs de classe de
stockage

Syntaxe

__declspec( naked ) déclarateur

L'utilisation de l'argument naked permet de supprimer le code prologue
et épilogue. Veillez à ce que l'utilisation de __declspec(naked) ne
définisse pas un cadre de pile normal. Une fonction avec
__declspec(naked) ne conserve pas les valeurs de registre
habituellement conservées. Il revient au programmeur de respecter les
conventions attendues par l'appelant de la fonction.
Vous pouvez utiliser cette fonctionnalité pour écrire votre propre
code prologue et épilogue à l'aide de code assembleur en ligne. Les
fonctions naked sont particulièrement utiles pour l'écriture de
pilotes de périphériques virtuels.

L'attribut naked ne concerne que la définition d'une fonction et n'est
pas un modificateur de type.
Exemple
Le code suivant définit une fonction à l'aide de l'attribut naked :

// Exemple d'attribut naked
__declspec( naked ) int func( formal_parameters )
{
// corps de la fonction
}
</C++Builder help>

En espérant que ça pourra vous aider dans votre version, ce qui n'est
pas certain...
--
Pierre

Avatar
Sivaller
"Yann Renard" a écrit
dans le message de news:41ad7f00$0$11925$
Sivaller wrote:

Je fais une fonction qui ressemble à ceci :
void _handlerdepipe()
{
_asm {
push ds
push bp
...
...
pop ds
pop bp
ret ;routine NEAR
}

Le compilateur me génére en supplément
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
//code de ma routine
push ds
push bp
...
...
pop ds
pop bp
ret ;routine NEAR
//
POP DI
POP SI
POP BP
RET

Ce qui est écrit en majuscule est la garniture inserer par le compilo.
Je souhaiterai que le compilateur ne me génére pas cette garniture (mov
bp,sp etc. ) sur ma fonction écrite en assembleur.
Comment faire ?

BORLAND C++ V4.02 (x86 16bits)

Merci


Ce n'est clairement pas une question concernant le C++ !!

Néanmoins, voici ce que je peux dire concernant ton problème : les
registres sauvegardés par le compilateur borland correspondent, si ma
mémoire est bonne, aux registres d'offset de code et de données, ainsi
que le pointeur de pile. Il les restaure à la sortie, en considérant
sans doute que c'est le minimum nécessaire pour garantir une bonne
continuation de l'execution du programme. Je pense que tu peux modifier
cela dans les options de compilations.

Un truc qui risque d'etre plus génant dans ce code :
_asm {
push ds
push bp

...

pop ds
pop bp
oui plutot

pop bp
pop ds
j'avais fais une erreur
}

j'espere que tu es bien conscient que ds et bp sont inversés à la sortie
de ta fonction :) tu ne restaures donc pas correctement le contexte
d'execution.

Bon courage,

Yann Renard



Avatar
Sivaller
__declspec(naked)
ne marche pas sachant que j'ai Borland C++ v4.02;
Avatar
Pierre Maurette
"Sivaller" a écrit:

__declspec(naked)
ne marche pas sachant que j'ai Borland C++ v4.02;
Pas de chance. Votre problème (si problème il y a) a une solution

simple qui est dans la doc du compilo.

- Voyez dans les commutateurs de la ligne de commande un truc comme
"générer cadres de pile", peut-être "generate stack frames" en
british, et testez.

- Cherchez "conventions d'appel" dans la doc, sur des mots comme
cdecl, fastcall, register, etc. Testez.

- Voyez et testez peut-être "inline". Mais autant une macro.

- Remplacez votre fonction void f(void) par une macro, ou utilisez
CtrlC/CtrlV ;-)

Sans développer trop longuement, faire une fonction et être géné par
le temps de 5 instructions machine n'est pas cohérent.

La doc actuelle de BASM stipule:
"Une instruction asm doit conserver les registres EDI, ESI, ESP, EBP
et EBX, mais peut librement modifier les registres EAX, ECX et EDX. A
l'entrée d'une instruction asm, EBP pointe sur le cadre de pile actuel
et ESP pointe sur le haut de la pile. A l'exception de ESP et EBP, une
instruction asm peut présumer qu'il n'y a rien dans le contenu du
registre à l'entrée de l'instruction."
Ce qui explique le code généré par le compilo. Ça montre aussi que du
code inline, et donc une macro, ne garantit pas la performance. A part
le cadre de pile qui existe déjà, le bloc asm peut amener des
sauvegardes ou des contraintes.

Si votre code asm est dans une boucle telle que les 5 instructions
machine gênent, le mieux est certainement de faire un bloc/fonction
asm plus grande, et de gérer la boucle en asm.

--
Pierre