Warum ist die Ausgabe dieses einfache Programm so viele Zeichen?
Frage
Hier ist meine kurz Montageprogramm:
; 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
Was ist das Programm sollte zu tun ist, Druck 5.5, aber es druckt:
-4101885043414705786563701568963176764603483495211119243453355953219830430011006780068899468997203661787555969981250050126586203424320244681571103387315766489883301796219461838644670607029711305942610787622864198879363376953745160639821663444829839767678538571371627347101810056161000273217639447052410683392.000000
Was auf der Erde mache ich falsch? Der Code drückt die beiden Argumente printf()
und nannte es dann. Nichts kompliziert.
Update: Ich war ein wenig verfrüht denke, ich dieses Problem behoben hatte. Ich habe den Code aktualisiert.
Lösung
Die Anweisung push f_0
schiebt die Adresse f_0 auf dem Stapel, nicht die 5.5 im Speicher gibt, so dass die printf Routine nehmen Sie die Adresse sowie die gespeicherte EBP (die nächsten 4 Bytes auf dem Stack) und die Bits als ein interpretieren verdoppeln und drucken sie es aus. Das macht sich als eine sehr große Zahl sein, wie Sie sehen.
Sie müssen 8 Bytes von f_0
laden und diejenigen zu schieben. so etwas wie
move eax, f_0
push dword ptr [eax+4]
push dword ptr [eax]
Bearbeiten
Sie müssen 8 Bytes drücken als FP64 Werte sind 8 Bytes. FP64 ist alles, was printf weiß, wie zu drucken - in der Tat FP64 ist alles, was C weiß, wie man Funktionen übergeben oder arbeiten auf. FP32 Wert kann nur vom und zum Speicher gespeichert geladen werden, sondern wird immer implizit umgewandelt FP64 (oder größer), bevor sie auf betrieben wird. Wenn Sie einen FP32 Wert laden möchten, wandeln es FP64, und schieben Sie es auf dem Stack, können Sie
verwendenfld dword ptr [f_0]
sub esp, 8
fstp qword ptr [esp]
Diese tatsächlich lädt ein FP32 Wert und wandelt sie in FP80 (die x87-internen Format), dann wandelt das FP80 Wert FP64 und speichert sie auf dem Stapel.