Pourquoi ce programme simple délivrer en sortie tant de personnages?
Question
Voici mon court assemblage programme :
; This code has been generated by the 7Basic
; compiler <http://launchpad.net/7basic>
extern printf
; Initialized data
SECTION .data
f_0 dd 5.5
printf_f: db "%f",10,0
SECTION .text
; Code
global main
main:
push ebp
mov ebp,esp
push dword [f_0]
push printf_f
call printf
add esp,8
mov esp,ebp
pop ebp
mov eax,0
ret
Qu'est-ce que le programme est supposé à faire est d'imprimer 5.5, mais il imprime:
-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000
Que diable suis-je tort? Le code pousse les deux arguments à printf()
puis l'appeler. Rien de compliqué.
Mise à jour: Je suis un peu prématuré de penser que j'avais résolu ce. J'ai mis à jour le code.
La solution
Le push f_0
d'instruction pousse l'adresse de f_0 sur la pile, et non le 5,5 en mémoire là-bas, de sorte que la routine printf prendra l'adresse, ainsi que le ebp enregistré (les 4 octets suivants de la pile) et interpréter les bits en tant que le double et l'imprimer. Qui se révèle être un très grand nombre, comme vous le voyez.
Vous devez charger 8 octets de f_0
et pousser ceux-ci. quelque chose comme
move eax, f_0
push dword ptr [eax+4]
push dword ptr [eax]
modifier
Vous devez pousser 8 octets comme FP64 valeurs sont 8 octets. FP64 est tout ce que printf sait comment imprimer - en fait FP64 est tout ce que C sait comment passer à des fonctions ou opérer. FP32 valeur ne peut être chargée à partir et stockées dans la mémoire, mais sont toujours converties implicitement FP64 (ou plus) avant d'être opéré. Si vous voulez charger une valeur FP32, convertir FP64, et le pousser sur la pile, vous pouvez utiliser
fld dword ptr [f_0]
sub esp, 8
fstp qword ptr [esp]
en fait des charges d'une valeur de FP32 et le convertit en FP80 (format interne du x87), puis convertit cette valeur FP80 à FP64 et le stocke sur la pile.