Printing To Screen: Difference between revisions

→‎Printf: The explanations were not enough to base a stdarg.h implementation upon them, factually not quite correct, and as such probably more confusing than helpful.
[unchecked revision][unchecked revision]
(→‎Printing Integers: '''If''' we provide example code, we could just as well go the full distance. ;-))
(→‎Printf: The explanations were not enough to base a stdarg.h implementation upon them, factually not quite correct, and as such probably more confusing than helpful.)
Line 105:
== Printf ==
 
If you're working with C, you may want to print any number of arguments, andlike <tt>printf()</tt> does. For this, you mayneed haveto handle variable argument lists. lookedLooking at the <tt>stdarg.h</tt> file from other Operatingoperating Systemssystems (e.g. linuxLinux 0.1), andyou Thixmight 0.3.x).be Thesea macrobit definitionsconfused mayby bethe amacro bitdefinitions weirdin tothat understandfile, as they're are basically Cblack voodoomagic usingdepending pointerson andthe castsC andcalling sizeofconventions. BewareAs beforesuch, portingthey themare tonot 16 bit systems,exactly thoughportable.
 
The good news are that <tt>stdarg.h</tt> is part of a freestanding implementation, so you can #include it even from your kernel source files. Under [[GCC]], the following simple implementation uses the gcc's built-in functionality to do all the work for you:
<tt>va_start()</tt> points to the first variable argument.
<tt>va_arg()</tt> advances the pointer, then evaluates to the previous argument (comma operator).
<tt>va_end()</tt> doesn't do anything.
 
The good news are that stdagr.h is part of the required features for freestanding implementations, so you can #include it even from your kernel source files.
 
'''Example:'''
 
To implement <tt>va_start()</tt>, you extract the address of the last 'known' argument and advance (yes, it's a <tt>+</tt> since you're rewinding the stack) to the next stack item. The voodoo comes to the fact that things are automatically aligned on 32bits boundary on the stack, even if just 1 byte. This approach however only works on x86 and also depends on the calling convention. Some calling conventions like fastcall, or on other architectures like x86-64 this approach doesn't work because the parameters are passed in registers and/or stack. Under [[GCC]], the following simple implementation uses the gcc's built-in functionality to do all the work for you:
<pre>
#define va_start(v,l) __builtin_va_start(v,l)
Line 124 ⟶ 117:
</pre>
 
YouAn canimplementation getof <tt>stdarg.h</tt> and <tt>printf()</tt> is available from geezer/osd ([http://my.execpc.com/~geezer/osd/code/inc/stdarg.h stdarg.h], [http://my.execpc.com/~geezer/osd/code/inc/_printf.h _printf.h] and, [http://my.execpc.com/~geezer/osd/code/tinylib/stdio/doprintf.c doprintf.c] from geezer/osd).
Not using those, <tt>va_arg()</tt> requires a bit more black magic since you have two things to do:
* advance to the next item
* return the value of the (previously current) item
 
You can get [http://my.execpc.com/~geezer/osd/code/inc/stdarg.h stdarg.h], [http://my.execpc.com/~geezer/osd/code/inc/_printf.h _printf.h] and [http://my.execpc.com/~geezer/osd/code/tinylib/stdio/doprintf.c doprintf.c] from geezer/osd.
 
Also, Solar's public[http://pdclib.rootdirectory.de domainPublic cDomain libraryC Library] has a starg.hthose implementationimplementations as well.
 
== Troubleshooting ==
448

edits