Ich versuche 32bit float
in 64bit double
in Asm auf x86-Architektur zu konvertieren. Die Umwandlung erfolgt durch eine in asm geschriebene Funktion und dann möchte ich sie von C aus aufrufen. Ich habe keine Ahnung, was ich falsch mache, aber der Speicher von dst
scheint unberührt zu bleiben und nach printf
stürzt das Programm ab. Ich möchte es ohne irgendwelche Gleitkommaanweisungen tun. Hier ist der Code:float to double (IEEE754) Umwandlung
.686
.model flat
public _conv
.data
mantissa_mask dd 00000000011111111111111111111111b
exponent_mask dd 01111111100000000000000000000000b
.code
_conv PROC
pusha
mov ebp, esp
mov esi, dword ptr [ebp+8] ; src
mov edi, dword ptr [ebp+12]; dst
mov dword ptr [edi], 0
mov dword ptr [edi+4], 0
mov eax, dword ptr [esi]
and eax, dword ptr mantissa_mask
mov dword ptr [edi], eax
xor edx, edx ; zero edx
mov ecx, 1
shl ecx, 29 ;ecx == 2^29
mul ecx ;so it's like `shl edx:eax, 29`
mov dword ptr [edi], eax
mov dword ptr [edi+4], edx
mov eax, dword ptr [esi]
and eax, dword ptr exponent_mask
shr eax, 23 ;put exponent on lowest bits
sub eax, 127 ;exponent in float is coded enlarged by 127
add eax, 1023 ;in double it's enlarged by 1023
shl eax, 20 ;exponent in double starts on 20bit of 2nd byte
or dword ptr [edi], eax
;sign bit:
bt dword ptr [esi], 31
jc set_sign_bit
btr dword ptr [edi+4], 31
jmp endthis
set_sign_bit:
bts dword ptr [edi+4], 31
endthis:
popa
ret
_conv ENDP
END
Und der C-Code:
void conv(float * src, double * dst);
int main()
{
float src = 4.5f;
double dst = 0.;
conv(&src, &dst);
printf("%f\n", dst);
return 0;
}
Stellen Sie sicher, dass Sie nicht versehentlich als 64-Bit kompilieren. Stellen Sie auch 'dst' auf ungleich Null, damit Sie prüfen können, ob es tatsächlich berührt wurde. Und verwenden Sie wie immer einen Debugger. – Jester
Sie sollten etwas debuggen. –
@Jester Ich hatte einige Bugs, die ich gerade gefunden habe. Entschuldigung dafür, ich habe Code in der Frage bearbeitet. – Criss