Bran's tutorial - putch()
Bran's tutorial - putch()
the puts(), putch() function, given in bran's tutorial, prints all the strings, characters corectly on the console.
but the funtion putch() is unable to print any integer value on the console. the function does nothing when asked to print any integer value.
i tried it this way (as given in tutorial) :-
int i;
i = 10/2;
puthch(i);
what could be the problem???
any help.... thanks in advance
cheers
but the funtion putch() is unable to print any integer value on the console. the function does nothing when asked to print any integer value.
i tried it this way (as given in tutorial) :-
int i;
i = 10/2;
puthch(i);
what could be the problem???
any help.... thanks in advance
cheers
Re:Test kernels refuses to print to screen
I get an access error on osdever.net ATM, and putch() isn't a standard function, so this is guesswork. But:vibhory2j wrote: the puts(), putch() function, given in bran's tutorial, prints all the strings, characters corectly on the console.
but the funtion putch() is unable to print any integer value on the console.
1) you didn't really write [tt]puthch(i);[/tt], I hope, as this is spelled incorrectyl;
2) are you sure that putch() is actually intended to print integers? Try feeding it values between, say, 65 and 90. If you see uppercase characters, that putch() accepts int but interprets them as char values. That is common in C I/O, to make room for the non-char value of EOF.
Every good solution is obvious once you've found it.
Re:Bran's tutorial - putch()
Yes, putch is intended for characters. To try and help you understand, vibhory2j, you may want to look up ASCII.
For the record, here is a method of writing a number to output that _SHOULD_ work:
For the record, here is a method of writing a number to output that _SHOULD_ work:
Code: Select all
void PrintInt(unsigned int a){
while(a > 0){
putch(a % 10);
a /= 10;
}
}
Re:Bran's tutorial - putch()
Your function prints last digit first, which probably is not what you intended, and makes the same mistake vibhory2j did originally (printing integers instead of character values), which is certainly not what you intended.Cjmovie wrote: For the record, here is a method of writing a number to output that _SHOULD_ work...
Here's code handling both int and unsigned int correctly, including sign and INT_MIN handling for twos-complement / ASCII machines. Untested but confident.
Code: Select all
#include <limits.h>
void PrintUInt( unsigned int a )
{
if ( a > 9 )
{
PrintUInt( a / 10 );
}
putch( ( a % 10 ) + '0' );
}
void PrintInt( int a )
{
if ( a < 0 )
{
putch( '-' );
if ( a == INT_MIN )
{
PrintUInt( ((unsigned int) INT_MAX) + 1 );
}
else
{
PrintUInt( a * -1 );
}
}
}
Every good solution is obvious once you've found it.
Re:Bran's tutorial - putch()
Your code eats the stack alive and doesn't handle with locales in which the minus should follow the number.Solar wrote:
Point being, you don't care about what it doesn't do or you'd end up with something like GNU Hello, which is the best example ever of an over-engineered project. It's a hello world, with autoconf, automake, locale support etc. Or try GNU True, which is a very long program that only returns true. Based on a define, which defines what it returns (the default program is called false).
Re:Bran's tutorial - putch()
Maximum recursion depth is 5 for 16bit, 10 for 32bit or 20 for 64bit. The version I showed works correctly regardless of word width and is simpler than one using an internal buffer. But well, since you asked for it, see bottom of this post...Candy wrote: Your code eats the stack alive...
I feel that kernel code should ignore locale issues because of the code bloat involved, especially in a minor case as to whether the minus should lead or trail. (And how numbers are usually grouped, e.g. commas every three digits etc.) You'd have to cater for EBCDIC, for example, where digits don't occupy consecutive places in the code tables......and doesn't handle with locales in which the minus should follow the number.
Agreed. But printing decimal numbers most-significant digit first is not negotiable IMNSHO.Point being, you don't care about what it doesn't do or you'd end up with something like GNU Hello, which is the best example ever of an over-engineered project.
Nice hint, I always wanted to learn about autoconf and automake.It's a hello world, with autoconf, automake, locale support etc.
But now for the non-recursive PrintInt() as requested by Candy:
Code: Select all
/* 5 for 16bit, 10 for 32bit, 20 for 64bit 'int' */
#define PRINTINT_MAXLEN 10
void PrintUInt( unsigned int a )
{
char buffer[ PRINTINT_MAXLEN + 1 ];
unsigned int p = PRINTINT_MAXLEN;
buffer[ p ] = '\0';
while ( a )
{
buffer[ --p ] = ( a % 10 ) + '0';
a /= 10;
}
puts( buffer + p );
}
Every good solution is obvious once you've found it.
Re:Bran's tutorial - putch()
Ooooh, last time I try to help out before school right after waking up from 2 hours of sleep while starting my history project due today.....Solar wrote:Your function prints last digit first, which probably is not what you intended, and makes the same mistake vibhory2j did originally (printing integers instead of character values), which is certainly not what you intended.Cjmovie wrote: For the record, here is a method of writing a number to output that _SHOULD_ work...
Here's code handling both int and unsigned int correctly, including sign and INT_MIN handling for twos-complement / ASCII machines. Untested but confident.
Code: Select all
#include <limits.h> void PrintUInt( unsigned int a ) { if ( a > 9 ) { PrintUInt( a / 10 ); } putch( ( a % 10 ) + '0' ); } void PrintInt( int a ) { if ( a < 0 ) { putch( '-' ); if ( a == INT_MIN ) { PrintUInt( ((unsigned int) INT_MAX) + 1 ); } else { PrintUInt( a * -1 ); } } }
lol
Re:Bran's tutorial - putch()
referring to the code by solar :-
i will try to put this in to my kernel. but i suspect the use of include file limits.h as we can't nse built in libraries in the kernel source.
am i right or wrong??? please clarify it....
cheers
Code: Select all
#include <limits.h>
void PrintUInt( unsigned int a )
{
if ( a > 9 )
{
PrintUInt( a / 10 );
}
putch( ( a % 10 ) + '0' );
}
void PrintInt( int a )
{
if ( a < 0 )
{
putch( '-' );
if ( a == INT_MIN )
{
PrintUInt( ((unsigned int) INT_MAX) + 1 );
}
else
{
PrintUInt( a * -1 );
}
}
}
am i right or wrong??? please clarify it....
cheers
Re:Bran's tutorial - putch()
Let me make a guess?
If the header file is going to call any system calls are other library routines then you can't have it in your kernel. Suppose if the header file is standalone library then you can have it in your kernel.Because i am doing kernel in asm i don't know much about C.
Please correct me if i am wrong?
If the header file is going to call any system calls are other library routines then you can't have it in your kernel. Suppose if the header file is standalone library then you can have it in your kernel.Because i am doing kernel in asm i don't know much about C.
Please correct me if i am wrong?
Re:Bran's tutorial - putch()
limits.h is part of the freestanding environment (The "not-running-on-an-OS" environment), basically it's just a header full of defines declaring "sizes" (ranges) of variable types.
If you built a cross compiler, <limits.h> will be part of your freestanding environment and should work fine (provided you aren't using "-nostdinc" on the commandline).
If you built a cross compiler, <limits.h> will be part of your freestanding environment and should work fine (provided you aren't using "-nostdinc" on the commandline).
Re:Bran's tutorial - putch()
You can use whatever part of the standard library you implemented. <limits.h> is so easy it can actually be auto-generated, as it merely contains a bunch of #define statements referring to the size of integers of your system.
Edit: You might want to have a look at my signature... PDCLib 0.2 isn't much from the user-space perspective, but it has all the freestanding headers (including <limits.h>), and is especially targeted at OS dev'ers like us here, meaning it's dead-easy to adapt to your wishes. Just stay away from the <string.h> functions until 0.3, there are some really stupid bugs in there.
Edit: You might want to have a look at my signature... PDCLib 0.2 isn't much from the user-space perspective, but it has all the freestanding headers (including <limits.h>), and is especially targeted at OS dev'ers like us here, meaning it's dead-easy to adapt to your wishes. Just stay away from the <string.h> functions until 0.3, there are some really stupid bugs in there.
Every good solution is obvious once you've found it.