Je suis novice en programmation d’assemblage et, en tant que partie d’un programme plus important, j’ai besoin de transmettre des valeurs à virgule flottante à une autre fonction C. J’ai un appel de mon programme de test à ma fonction d’assemblage, qui ne fait que pousser les parameters sur la stack de droite et appelle une deuxième fonction C.
Ma fonction de test C:
extern void ext_func(char *result, double d); // C function extern double tester(char *str, float d); double a = tester(str, 3.14) printf("%s\n", str); // Resulting in '0.000000' // doing some fancy stuff with the float value and puts in result ext_func(str, 3.14); // gives str = "3.140000"
x86, gcc -m32:
.globl tester tester: pushl %ebp # Standard movl %esp, %ebp # flds 12(%ebp) # Push second parameter on stack pushl 8(%ebp) call ext_func addl $4, %esp leave ret
Je pense qu’il y a un problème avec moi qui pousse seulement 32 bits quand ext_funct
attend le double. Mais j’ai essayé d’utiliser le fldl, fld1, fildl, les fldl 12 et 16 (% ebp), et quelques-uns des autres pour “fun”.
printf("%f", a); //3.140000 printf("%f", str); //3.140000
mais dans l’autre voie, a
grand nombre négatif (100 chiffres environ) se termine par 000000.
La convention 32 bits utilise la stack cpu pour transmettre des arguments en virgule flottante. Il utilise uniquement la stack fpu pour les retourner. Oui, vous devez convertir votre float 32 bits en un double 64 bits, conformément aux prototypes fournis.
Notez que ext_func
est void
, c’est-à-dire qu’il ne retourne rien, mais que vous avez déclaré le tester
comme renvoyant double
… on ne sait pas exactement ce que vous voulez renvoyer, je supposerai que vous voulez que le d
original soit renvoyé (pour une raison quelconque).
A ce titre, une implémentation possible pourrait être:
.globl tester tester: subl $12, %esp # allocate space for outgoing arguments movl 16(%esp), %eax # fetch our first argument (str) movl %eax, (%esp) # store as first outgoing argument flds 20(%esp) # Fetch our second argument as float fstpl 4(%esp) # store it as second outgoing argument as double call ext_func flds 20(%esp) # load d as return value addl $12, %esp # cleanup stack ret