Float to int conversion (using Bare Bones)

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.
marcio.f

Float to int conversion (using Bare Bones)

Post 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,
GLneo

Re:Float to int conversion (using Bare Bones)

Post by GLneo »

works fine for me try not having so many compile arguments like: -pedantic
marcio.f

Re:Float to int conversion (using Bare Bones)

Post 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?
GLneo

Re:Float to int conversion (using Bare Bones)

Post by GLneo »

nothing, my kernel compiles like this: gcc kern.c -o kern.o
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Float to int conversion (using Bare Bones)

Post 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.
Every good solution is obvious once you've found it.
marcio.f

Re:Float to int conversion (using Bare Bones)

Post 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';
marcio.f

Re:Float to int conversion (using Bare Bones)

Post 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?
marcio.f

Re:Float to int conversion (using Bare Bones)

Post by marcio.f »

Can someone help me out, please?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Float to int conversion (using Bare Bones)

Post 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. ;)
Every good solution is obvious once you've found it.
marcio.f

Re:Float to int conversion (using Bare Bones)

Post 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" ?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Float to int conversion (using Bare Bones)

Post 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.
Every good solution is obvious once you've found it.
GLneo

Re:Float to int conversion (using Bare Bones)

Post 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 :-\
marcio.f

Re:Float to int conversion (using Bare Bones)

Post 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 :)
AR

Re:Float to int conversion (using Bare Bones)

Post 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.
marcio.f

Re:Float to int conversion (using Bare Bones)

Post 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.
Post Reply