Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++ function definitions without assembly

I always thought that functions like printf() are, in the last step, defined using inline assembly. That deep in the bowels of stdio.h is buried some asm code that actually tells CPU what to do. For example, in dos, I remember it was implemented by first moving the beginning of the string to some memory location or register and than calling an intterupt.

However, since the x64 version of Visual Studio doesn't support inline assembler at all, it made me wonder how there could be no assembler-defined functions at all in C/C++. How does a library function like printf() get implemented in C/C++ without using assembler code? What actually executes the right software interrupt? Thanks.

like image 885
Jack Avatar asked Mar 14 '10 17:03

Jack


People also ask

What are two parts of function definition in C?

A function consist of two parts: Declaration: the function's name, return type, and parameters (if any) Definition: the body of the function (code to be executed)

What are the components of a function definition?

A function has three parts, a set of inputs, a set of outputs, and a rule that relates the elements of the set of inputs to the elements of the set of outputs in such a way that each input is assigned exactly one output.

Can I write assembly in C?

We can write assembly program code inside c language program. In such case, all the assembly code must be placed inside asm{} block.

What happens if one of the argument names in a function declaration does not match that of the corresponding function definition?

It is an error if the number of arguments in a function definition, declaration, or call does not match the prototype. If the data type of an argument in a function call does not match the corresponding type in the function prototype, the compiler tries to perform conversions.


1 Answers

First, you have to understand the concept of rings.
A kernel runs in ring 0, meaning it has a full access to memory and opcodes.
A program runs usually in ring 3. It has a limited access to memory, and cannot use all the opcodes.

So when a software need more privileges (for opening a file, writing to a file, allocating memory, etc), it needs to asks the kernel.
This can be done in many ways. Software interrupts, SYSENTER, etc.

Let's take the example of software interrupts, with the printf() function:
1 - Your software calls printf().
2 - printf() processes your string, and args, and then needs to execute a kernel function, as writing to a file can't be done in ring 3.
3 - printf() generates a software interrupt, placing in a register the number of a kernel function (in that case, the write() function).
4 - The software execution is interrupted, and the instruction pointer moves to the kernel code. So we are now in ring 0, in a kernel function.
5 - The kernel process the request, writing to the file (stdout is a file descriptor).
6 - When done, the kernel returns to the software's code, using the iret instruction.
7 - The software's code continues.

So functions of the C standard library can be implemented in C. All it has to do is to know how to call the kernel when it need more privileges.

like image 196
Macmade Avatar answered Oct 14 '22 06:10

Macmade