Мне нужно записать значение REAL8 в файл в сборке x86 (у меня есть доступ к подпрограммам Irvine32.) Для этого мне нужно поместить значение в буфер, чтобы оно представляло правильное десятичное число.
Я искал везде и не нашел решения.
Вот код, любая помощь будет очень полезна, так как я застрял здесь. Я чувствую, что может быть более простое решение, чем я могу себе представить, но я в растерянности.
.data
TotalHops BYTE 0
BYTE 0
AverageHops REAL8 ? ; float average
FloatBuffer BYTE 8 DUP(0) ; buffer for printing to file
OutFile BYTE "Output File",0 ; output file handle
EXPONENT_BITS EQU
0111111111110000000000000000000000000000000000000000000000000000
MANTISSA_BITS EQU
0000000000001111111111111111111111111111111111111111111111111111
Exponent BYTE 3 DUP(0) ; MSB of Exponent will always be zero
(average negative)
Mantissa BYTE 7 DUP(0) ; Holds 52 bits
.code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Add two floating point values to stack
; Divide them
; Store result in AverageHops
; Call WriteRealToBuffer procedure to prep for file writing
; Print FloatBuffer to file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Float PROC
FINIT ; clear stack before we start
FILD ReachedPackets ; converts int ReachedPackets to float, loads onto FPU register stack
; ST(0) = ReachedPackets
FILD TotalHops ; converts int TotalHops to float, loads onto FPU register stack
; ST(0) = TotalHops
; ST(1) = ReachedPackets
FDIV ; divides TotalHops by ReachedPackets
; ST (0) contains result
FSTP AverageHops ; stores result in AverageHops, pops stack
;Set up buffer for writing real to file
call WriteRealToBuffer
;Write AverageHops to file:
MOV edx, OFFSET OutFile
call CreateOutputFile ; eax contains verification of successful file creation
;handle writing from buffer
FINIT ; clear everything when done
Float ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Write REAL8 to buffer for file writing
; First bit (bit 63) is sign [will always be 0 (never negative average)]
; Bits 62-52 are E
; Subtract 1023 from E to remove bias (gives us e)
; This new value is our exponent (e)
; Bits 51-0 are fraction (mantissa)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WriteRealToBuffer PROC
;Save registers
PUSH EAX
;Get the Exponent bits
MOV eax, AverageHops
AND eax, EXPONENT_BITS
MOV Exponent, eax
;Subtract 1023 to remove bias
SUB Exponent, 1023d
;Get the mantissa
MOV eax, AverageHops
AND eax, MANTISSA_BITS
MOV Mantissa, eax
;What to do:
; look at mantissa
; read until rest is 0's
; that binary value is multiplied by 10^e, where 'e' is what we have in
Exponent
; For buffer:
; convert left side of decimal point to decimal form
; add to buffer
; add decimal point to buffer
; convert right side of decimal point to decimal
; add to buffer
#########################################################
#### Single-Precision Example Table ###############
### We Use Double-Precision, don't forget ##########
#########################################################
#BinValue # Biased exp (E) # Sign, Exponent, Fraction #
#########################################################
# -1.11 # 127 # 1 01111111 1100000000...##
# +1101.101 # 130 # 0 10000010 1011010000...##
# -0.00101 # 124 # 1 01111100 0100000000...##
# +100111.0 # 132 # 0 10000100 0011100000...##
#########################################################
POP eax
WriteRealToBuffer ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;