Page 1 of 3

Float to int conversion (using Bare Bones)

Posted: Wed Jul 13, 2005 2:09 pm
by marcio.f
Hi,

I'm using a cross-compiler and a bare bones kernel just like in the OS-FAQ. These are the gcc flags I use:
-ffreestanding -g -Wall -ansi -pedantic -Werror -nostdlib -nostartfiles -nodefaultlibs

Now for the problem, running this code:

Code: Select all

void _main(void* mbd, unsigned int magic)
{
   float a;
   a = 7.63;

   ((char *)0xB8000)[0] = ((int)a)+'0';
   
   while (1);
}
should write '7' in line 0, column 0, but instead writes '0'. I think this is happenning because the cast makes it convert to 0 (zero). Why that happens, I don't know. Can someone help me?

Thanks in advance,

Re:Float to int conversion (using Bare Bones)

Posted: Wed Jul 13, 2005 3:10 pm
by GLneo
works fine for me try not having so many compile arguments like: -pedantic

Re:Float to int conversion (using Bare Bones)

Posted: Wed Jul 13, 2005 3:24 pm
by marcio.f
GLneo wrote: works fine for me try not having so many compile arguments like: -pedantic
I think it's not because of that as it's only a warning option (see "man gcc" and search for pedantic).
What did you use/do to test it?

Re:Float to int conversion (using Bare Bones)

Posted: Wed Jul 13, 2005 3:56 pm
by GLneo
nothing, my kernel compiles like this: gcc kern.c -o kern.o

Re:Float to int conversion (using Bare Bones)

Posted: Wed Jul 13, 2005 10:06 pm
by Solar
Definitely not a thing of the GCC options used. -pedantic or -ansi don't change what the code does, it merely adjusts which GCC extensions are enabled and which language version is used. Anyway, in the worst case you get a compiler diagnostic where you didn't get one before, but you don't get a different output.

I would suspect that your 7.62 didn't make it into the object file because of your linker setup (not linking in all necessary sections). An objdump could help.

Sorry but I'm right now wolfing down my breakfast and then have to catch the train, so I can't test it. But I'm 90% sure that's where the bug is.

Re:Float to int conversion (using Bare Bones)

Posted: Thu Jul 14, 2005 2:12 am
by marcio.f
Solar wrote:I would suspect that your 7.62 didn't make it into the object file because of your linker setup (not linking in all necessary sections). An objdump could help.
I don't know why is that because I've done just like in the Bare Bones section. Anyway, attached is objdump output.

EDIT: found that this code works ???

Code: Select all

   ((char *)0xB8000)[0] = ((int)7.63)+'0';

Re:Float to int conversion (using Bare Bones)

Posted: Thu Jul 14, 2005 8:51 am
by marcio.f
GLneo wrote: nothing, my kernel compiles like this: gcc kern.c -o kern.o
Can I see the kernel code you used and linker script?

Re:Float to int conversion (using Bare Bones)

Posted: Sat Jul 16, 2005 1:13 am
by marcio.f
Can someone help me out, please?

Re:Float to int conversion (using Bare Bones)

Posted: Sat Jul 16, 2005 1:20 am
by Solar
I don't have a Cygwin cross-compiler handy right now (don't need one anymore), and am in the process of building one so I can reproduce your problem. Bear with me, my weekends are about as busy as my working days. ;)

Re:Float to int conversion (using Bare Bones)

Posted: Sat Jul 16, 2005 1:23 am
by marcio.f
Solar wrote: I don't have a Cygwin cross-compiler handy right now (don't need one anymore), and am in the process of building one so I can reproduce your problem. Bear with me, my weekends are about as busy as my working days. ;)
Many thanks, I'm looking forward for your help :)
...can you tell me why you said "don't need one anymore" ?

Re:Float to int conversion (using Bare Bones)

Posted: Sun Jul 17, 2005 4:00 am
by Solar
Using Linux these days. ;)

Sorry but the Cygwin died on me. I'll have to make another run at it. Might be Tuesday before I find the time.

Re:Float to int conversion (using Bare Bones)

Posted: Sun Jul 17, 2005 3:14 pm
by GLneo
what do you need float for, i've built my entier os(semi-posix campatible, dos clone, with pagin + fat, ext..) not using float 1 time (exept std header whitch arnt part of my kernel so get compiled exturnaly) try doing stuff w/o it :-\

Re:Float to int conversion (using Bare Bones)

Posted: Sun Jul 17, 2005 3:48 pm
by marcio.f
@GLneo:
First, I might not need it in the short time but I certainly will in the long time ;)
Second, right now I'm coding the printf function. Of all the supported conversion characters, all that's left to me are the ones who deal with float/double numbers, namely: f, e, E, g, G.
This is why I need to know what's causing my ?problem?.

@Solar:
Don't worry. Again, thanks :)

Re:Float to int conversion (using Bare Bones)

Posted: Sun Jul 17, 2005 5:20 pm
by AR
You shouldn't need float, using floating point in the kernel will not be good for system performance unless you intend to deny access to floating point features to user space programs. Saving the floating point state everytime you enter the kernel will slow system calls, not even Windows does this (although admittedly Windows does provide an API for forcing the floating point state to be saved in drivers).

If you aren't actually performing math and just using variables then hopefully GCC won't optimize by storing the value in a floating point register (you can force prevent this using -msoft-float IIRC).

Try turning "a" into a const global then objdump to see where it is in the binary, if it doesn't show up or shows up in a weird location then there is probably something wrong with the way it's linked.

Re:Float to int conversion (using Bare Bones)

Posted: Mon Jul 18, 2005 3:07 am
by marcio.f
Thanks for your reply.

I don't *really* need float numbers right now, as I previously said I'm just coding the printf function. Not too worried about system performance because, for me, this is just a hobby and a way to learn a little more about operating systems ;)

But I confess I didn't understand very well what you said about "floating point state"..

Anyway, I tried the "-msoft-float" flag:

Code: Select all

rm -f -v *.o *.bin
removed `kernel.o'
removed `loader.o'
/usr/cross/bin/i586-elf-as -o loader.o init/loader.s
/usr/cross/bin/i586-elf-gcc -msoft-float -ffreestanding -g -Wall -ansi -pedantic -Werror -nostdlib -nostartfiles -nodefaultlibs -o kernel.o -c kernel.c
/usr/cross/bin/i586-elf-ld -T linker/linker.ld -o kernel.bin loader.o kernel.o
kernel.o(.text+0x15): In function `_main':
/home/marciof/kernel.c:7: undefined reference to `__fixsfsi'
make: *** [kernel.bin] Error 1
And as you said, I made "a" a global constant:

Code: Select all

const float a = 7.63;

void _main(void* mbd, unsigned int magic)
{   
   ((char *)0xB8000)[0] = ((int)a)+'0';

   while (1);
}
The objdump is attached.