ParameterÜbergabe

02/08/2008 - 20:03 von Jens Kallup | Report spam
Hallo

habe nun den folgenden Code generiert:

-
BITS 32
cpu 486


section .data
LClassProperty_top: dw 1
LClassPropertyValue_top: dd 200.0
LClassProperty_height: dw 4
LClassPropertyValue_height: dd 340.0
LClassProperty_left: dw 2
LClassPropertyValue_left: dd 250.0
LClassProperty_width: dw 3
LClassPropertyValue_width: dd 890.0

section .text
extern Fix2Gleit, Ausgabe
extern _set_this_wert
global _start_main
_start_main:
push ebp
mov ebp, esp
sub esp, 32
push LClassType_masterforma
call LClassName_masterforma
leave
ret

section .data
LClassType_masterforma: dw 1
LClassNameStr_masterforma: db "masterforma",0

section .text
LClassName_masterforma:
push ebp
mov ebp, esp
sub esp, 32
push dword LClassNameStr_masterforma
push dword [LClassProperty_top]
push dword [LClassPropertyValue_top]
call _set_this_wert
add esp, 12
push dword LClassNameStr_masterforma
push dword [LClassProperty_height]
push dword [LClassPropertyValue_height]
call _set_this_wert
add esp, 12
push dword LClassNameStr_masterforma
push dword [LClassProperty_left]
push dword [LClassPropertyValue_left]
call _set_this_wert
add esp, 12
push dword LClassNameStr_masterforma
push dword [LClassProperty_width]
push dword [LClassPropertyValue_width]
call _set_this_wert
add esp, 12
leave
ret

bis auf den letzten _set_this_wert call làuft alles 1a.
das/der letzte "LClassProperty_width" Wert ergibt in der Ausgabe
keine 3, sondern -21.

desweiteren: wenn ich nun
"LClassPropertyValue_top: dd 200.20" definiere, kommt als Ausgabe
200.199997 raus und LClassProperty_top 858

danke für hilfe und ideen für einen workaround
Jens
 

Lesen sie die antworten

#1 Ralph rkhb Bauer
02/08/2008 - 22:20 | Warnen spam
Jens Kallup schrieb:
LClassProperty_width: dw 3
LClassPropertyValue_width: dd 890.0


(...)
push dword [LClassProperty_width]
push dword [LClassPropertyValue_width]
call _set_this_wert


(...)

bis auf den letzten _set_this_wert call làuft alles 1a.
das/der letzte "LClassProperty_width" Wert ergibt in der Ausgabe
keine 3, sondern -21.



LClassProperty_width ist ein WORD ('dw' heißt 'data word'). Gepusht wird
aber ein DWORD. Entweder stellst Du oben um:

LClassProperty_width: dd 3 ; 'dd' heißt 'data dword'

oder unten:

push word [LClassPropertyValue_width]

Damit wird LClassPropertyValue_width aber noch nicht zu einem FLOAT, so dass

(...) int set_this_wert(float wert, float pt, char *cn)

die Übergaben völlig falsch interpretiert. Entweder Du stellst oben um:

LClassProperty_width: dd 3.0 ; mit Punkt interpretiert es NASM als Single.

oder unten:

(...) int set_this_wert(float wert, short pt, char *cn)

VORSICHT: Die Größe von FLOAT ist im C-Standard nicht definiert, so dass
jeder Compiler damit sein eigenes Spielchen spielen kann. Wàhrend FLOAT beim
GCC ein Single (DWORD) ist, ist es bei Visual-C++ ein Double (QWORD).

desweiteren: wenn ich nun
"LClassPropertyValue_top: dd 200.20" definiere, kommt als Ausgabe
200.199997 raus



Darüber stolpert jeder. Da 0.2 dezimal in binàr eine unendliche Folge
ergibt, muss die Gleitkommazahl gerundet werden. Das ist genauso, wie wenn
du den Bruch 1/3 in eine dezimale Zahl umrechnen willst. Rechne mal Deine
Zahl per Hand in ein Single um, wie es in

http://de.wikipedia.org/wiki/IEEE_754

beschrieben ist. Der Artikel ist übrigens wirklich zu empfehlen.

Eine explizite Pràzisionsangabe bei sprintf bringt Besserung:

sprintf(buffer,"--> %s, we: %.5f, pt: %.5f",cn,wert,pt);

viele grüße
ralph

Ähnliche fragen