Printing To Screen: Difference between revisions

Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(Removed PFR tag)
No edit summary
Line 61: Line 61:
(see more on [http://www.osdev.org/phpBB2/viewtopic.php?t=10319 the forum].)
(see more on [http://www.osdev.org/phpBB2/viewtopic.php?t=10319 the forum].)


==Printf==
== Printf ==


If you're working with C, you may want to print any number of arguments and you may have looked at the <tt>stdarg.h</tt> file from other Operating Systems (e.g. linux 0.1 and Thix 0.3.x). These macro definitions may be a bit weird to understand as they're basically C voodoo using pointers and casts and sizeof. Beware before porting them to 16 bit systems, though.
If you're working with C, you may want to print any number of arguments and you may have looked at the <tt>stdarg.h</tt> file from other Operating Systems (e.g. linux 0.1 and Thix 0.3.x). These macro definitions may be a bit weird to understand as they're basically C voodoo using pointers and casts and sizeof. Beware before porting them to 16 bit systems, though.
Line 69: Line 69:
<tt>va_end()</tt> doesn't do anything.
<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.
E.g. 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 <tt>_builtin_next_arg()</tt> function may help you and works cross-platform. Versions 3.x even seem to have <tt>_builtin_va_start()</tt>, <tt>_builtin_va_end()</tt> and <tt>_builtin_va_arg()</tt> so no black magic is required at all.

'''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 <tt>_builtin_next_arg()</tt> function may help you and works cross-platform. Versions 3.x even seem to have <tt>_builtin_va_start()</tt>, <tt>_builtin_va_end()</tt> and <tt>_builtin_va_arg()</tt> so no black magic is required at all.


<tt>va_arg()</tt> usually require a bit more black magic since you have two things to do:
<tt>va_arg()</tt> usually require a bit more black magic since you have two things to do:
Line 79: Line 83:
Also, Solar's public domain c library has a starg.h implementation as well.
Also, Solar's public domain c library has a starg.h implementation as well.


==Troubleshooting==
== Troubleshooting ==


===Nothing is Displayed===
=== Nothing is Displayed ===


Keep in mind that this way of writing to video memory will _only_ work if the screen has been correctly set up for 80x25 video mode (which is mode 03). You can do this either by initializing every VGA register manually or by calling the Set Video Mode service of the BIOS Int10h while you're still in real mode (in your bootsector, for instance). Most BIOS's does that initialization for you, but some other (mainly on laptops) do not. Check out [[Ralf Brown's Interrupt List]] for details. Note also that some modes that are reported as "both text&graphic" by mode lists are actually graphic modes with BIOS functions that plot fonts when you call char/message output through Int10h (which means you'll end up with plain graphic mode once in [[Protected Mode]])
Keep in mind that this way of writing to video memory will _only_ work if the screen has been correctly set up for 80x25 video mode (which is mode 03). You can do this either by initializing every VGA register manually or by calling the Set Video Mode service of the BIOS Int10h while you're still in real mode (in your bootsector, for instance). Most BIOS's does that initialization for you, but some other (mainly on laptops) do not. Check out [[Ralf Brown's Interrupt List]] for details. Note also that some modes that are reported as "both text&graphic" by mode lists are actually graphic modes with BIOS functions that plot fonts when you call char/message output through Int10h (which means you'll end up with plain graphic mode once in [[Protected Mode]])