Thread: Writing own printf function without using stdarg.h

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    7

    Question Writing own printf function without using stdarg.h

    Hi,

    I am trying to write my own printf function . I dont want to use the stdarg.h since i am going to use this function in real mode (during booting). So i need to access the arguments from memory directly.

    I want to understand how the arguments are stored when they are passed to the stack. I am using the gcc compiler on linux to compile and run my programs ..

    I already have routines to print short, long, int and characters. This is how i plan to implement my function :

    int printf(char *str,...)

    Sample call : printf ("%c%d",'a',45)

    In printf , I will have the address of the string str so I will scan that and count the number of arguments and their types. Now using this information and the address of the first argument str, I need to get access to the other arguments on the stack .

    I dont want to add checks and just want basic functionality.

    Any help is appreciated.

  2. #2
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    GCC doesn't support real mode. I suggest you do what's required to be done in rm in asm, then get to pm and call your C code.

  3. #3
    Registered User
    Join Date
    Sep 2010
    Posts
    7
    Quote Originally Posted by User Name: View Post
    GCC doesn't support real mode. I suggest you do what's required to be done in rm in asm, then get to pm and call your C code.
    Thanks for the reply.

    I knw it doesnot support. I will compile using bcc (16-bit compiler) link it to my rountines in ASM and call c functions.
    The basic putchar function is written is ASM and i have used this putchar to write other routines like prints for string, and printd for printing integers.

    Now i need to write the printf rountine in C and call from ASM also to ease outputting to the screen.

    Reply back if not clear. I'll provide more info .

  4. #4
    Registered User
    Join Date
    Sep 2010
    Posts
    7
    When GCC calls your function, it pushes all its arguments onto the stack, starting with the last one, then issues a call. This means that, on entry to your function, the stack is laid out like this:

    Last argument
    ...
    4(%esp) First argument
    (%esp) Return address
    Sizes and layouts of individual arguments are as follows:

    Integers up to 32 bits and pointers are pushed as a single longword.
    long long int is pushed as two longwords; the least significant is pushed last (and so is located first in memory).
    float and double are pushed as a double-precision value, occupying 8 bytes.
    long double is pushed as an extended-precision value followed by 2 bytes of padding, totalling 12 bytes.
    As before, structures are more complicated and best avoided.
    These rules also apply to functions which take a variable number of arguments (like printf). As with any variadic function, the function must find its own way of determining how many arguments were actually passed (usually based on one of the required args).


    Now taking the above abstract in mind:
    why doesnt my code work :


    int testfn (int c,int v, int w)
    {
    printf("%d\n",*(&c));
    printf("%d\n",*(&c+4));
    printf("%d\n",*(&c+8));
    }
    int main(){
    testfn(34,45,56);
    }

    Output:
    34
    junk
    junk

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    In the future, please surround your code with code tags.
    Now taking the above abstract in mind:
    why doesnt my code work :
    It doesn't work because you've forgotten that pointer arithmetic scales by the size of the pointed-to type. Say an int is 4 bytes wide. A pointer to int plus 4 adds on 16 bytes (that is, 4 integers), not 4 bytes (which is one integer). So you probably want to try &c + 1 and &c + 2.

  6. #6
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    What's wrong with stdarg.h? Here's a link to my slightly flawed implementation of prinf and vprintf: My vprintf

  7. #7
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by cas View Post
    In the future, please surround your code with code tags.

    It doesn't work because you've forgotten that pointer arithmetic scales by the size of the pointed-to type. Say an int is 4 bytes wide. A pointer to int plus 4 adds on 16 bytes (that is, 4 integers), not 4 bytes (which is one integer). So you probably want to try &c + 1 and &c + 2.
    Isn't an integer 2 bytes anyway in 16-bit compiler?

    Quote Originally Posted by User Name: View Post
    What's wrong with stdarg.h? Here's a link to my slightly flawed implementation of prinf and vprintf: My vprintf
    Did you read his post? In real mode you can't use C standard library.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by maxorator View Post
    Isn't an integer 2 bytes anyway in 16-bit compiler?
    Not necessarily. The "16-bit" in the term "16-bit compiler" has variable meanings (i.e. different people will tell you it means different things). However, a relatively common meaning is that the "16-bit" refers to accessible address space - for example, the default size of a pointer.

    A 16-bit system will often support a 16-bit integer type, but that is coincidental - it is not unheard of for "int" supported by a 16-bit compiler to be 32-bit. Some older 16-bit compilers also allowed configuring (eg via command line options) the size of an int type.

    One practical reason that an int can be the same size as either a short or a long (and potentially both) was to allow for some oddball 16-bit compilers.
    Last edited by grumpy; 09-05-2010 at 03:51 AM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Isn't an integer 2 bytes anyway in 16-bit compiler?
    But even if that's the case, it doesn't matter. The point isn't that ints are 2 bytes, it's that they aren't (guaranteed to be) one byte.

  10. #10
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    You'll never have a one byte arg on the stack anyway. Pushing a byte is impossible, and even thought it is possible to manipulate sp to emulate it, it is standard for compilers to push chars as 2 or 4 bytes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems installing Mingw5.1.4
    By BlackOps in forum C Programming
    Replies: 2
    Last Post: 07-26-2009, 03:28 AM
  2. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  3. IF CONDITION plese help
    By birumut in forum C Programming
    Replies: 12
    Last Post: 03-06-2009, 09:48 PM
  4. Simple C question: user input to repeat a loop
    By evernaut in forum C Programming
    Replies: 2
    Last Post: 11-18-2006, 09:23 AM
  5. Drawing tables in C
    By stanoman in forum C Programming
    Replies: 5
    Last Post: 10-09-2003, 10:14 AM