Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Men,
I spent the whole day yesterday wondering why and debugging my printf that could not displaying the floating point variables I sent to it. Only to look at the object dump of my kernel and find out that Djgpp is the cause >:(
This is what I did,
void printf(unsigned char *format,...); // This the definition
I call my printf with
printf("%f",70.457);
Instead of Djgpp doing
push 0x428ce9fc
push [address of format string]
push [return address]
call _printf
Djgpp Now decides to
push 0x40519d3f
push [address of format string]
push [return address]
call _printf
which is WRONG!
I have called my float_to_string function defined
unsigned long float_to_string(float num,char * string);
which Djgpp handles properly.
Now I wonder why Djgpp can't send floats properly when they are one of the parameters in a variable length parameter list (Other data types are sent properly)! ANY solutions to this please?
thanks
ANSI C says that floats are extended to doubles when passed on variable parameter lists; they are not passed as floats. Would this explain what you're seeing?
Hum, ???
This is what the object dump of the part where i called float_to_string and printf in my kernel
push %eax
push $0x428ce9fc //this is what 70.457 look like in hex
call c0001582 <_ftoa> //calls Float_to_string which works
add $0x10,%esp //removes the parameter from stack
sub $0x4,%esp
push $0x40519d3f //this is what it pushes for 70.457
push $0x7ced9168 //I thought this was the return addess (but Now I'm Not sure)
push $0xc0007000
call c0004cb3 <_printf>
add $0x10,%esp
- UPDATE.....
It is WORKING NOW! Thanks Tim,I just had to use a (double *) to access the var_list instead of (float *) ;D
I need to READ the specification for C again imagine i spent a whole day wondering what was wrong. Thats why they say little things (fine details) are the things that count
Thanks!
I may be wrong, but as Call already pushes the EIP onto the stack (the return address), the return address does not need to be explicitly specified, so it looks like Tim is right in that it is converting a 4 byte float into a 8 byte double.
After all, why would you need to specify the return address? Isn't the 0xc0007000 simply the address of the format string? (Sounds likely, seeing as it looks like the beginning of a page, i.e. the start of a RO text section)
Yeah, Tim's right I updated my post above with this
- UPDATE.....
It is WORKING NOW! Thanks Tim,I just had to use a (double *) to access the var_list instead of (float *)
I need to READ the specification for C again imagine i spent a whole day wondering what was wrong. Thats why they say little things (fine details) are the things that count
Thanks!
ps: I wasn't specifing the return address just slipped up on my recollection of the call process which is
push all parameters
push return address by cpu atomatically when call is invoked
that's why they are called bugs, those small things *gg*
hmm.... and a double is pushed onto the stack in form of two ints - one holding the low portion of the double and the other one the high portion of it.