For the printf part, this is part of the C standard library, which is part of C. Thus, implementing your C compiler or C Standard library can use all kinds of tricks to make it work.
Let's look at a simple example of how such a function can be implemented on Unix. Take putchar (simplified here - returning nothing). It prints one character to standard output, which has file descriptor number 1. The operating system provides a "write" function. A program can be written to a file descriptor. So putchar can use this function:
void putchar(int c) { unsigned char cc = c; write(1, &cc, 1); }
Will write 1 byte to file descriptor 1. The write function will inform the operating system about this desire:
void write(int fd, void * ptr, size_t size) { asm("....." "int 0x80"); }
Usually it just contains a small block of assembly lines that causes a software interrupt (in the example above, this is the interrupt number 0x80). The CPU will switch to kernel mode and go to some fixed address from which the operating system can handle this interrupt. write will write the number of the system call to write to some register and put the arguments in any memory location or registers so that the operating system knows what to do at this point. Then, the operating system will send bytes that should be written to the specified file / device (in the case of stdout, this may be the terminal driver that is connected to the file descriptor), and will return from the interrupt by putting the CPU switch in user mode.
This is a rough plan. That is not all (the putschar can buffer the output before making a system call ...). But basically it works like that.
The MessageBox function will also call some system call at the end, which transfers control to the Windows kernel in one way or another, similar to the explanation above.
source share