Naked Function Calls in C++

Hello Everyone! Today we are going to learn about Naked Function Calls in C++. We would have a doubt why the function is call naked in C++. Before, knowing about it we should learn about what a function call is?

Function Call in C++

The process of activating the function and allowing it to run at the place where we require it to be executed in C++ Program is known as Function Call in C++.

There two types of function calls in C++. They are:

  • Function Call with Parameter

Here, in this function call we do assign or pass any parameters to the C++ Program. These Parameters play a crucial role in the running of the program.

  • Functions Call without Parameter

Here, in this function call we do assign or pass any parameters to the C++ Program. These Parameters play a crucial role in the running of the program.

Example

File name: withParameters1. cpp

Code

Input:

Output:

3628800 is the factorial of 10

Example

File name: withoutParameters1. cpp

Code

Input:

Output:

2004310016 is the factorial of 15

Naked Function Calls

When a function is declared with the naked property, no prolog or epilog code is generated, allowing you to use the inline assembler to create your own unique prolog/epilog sequences.

An advanced feature is the availability of naked functions. They provide you the option to declare a function that is being called from a context other than C or C++, allowing you to base assumptions about the location of parameters or the preservation of registers differently.

Routines like interrupt handlers are examples. The creators of virtual device drivers (VxDs) will find this functionality especially very handy or easy to use.

The naked property is used to specify functions, and when code is generated for such functions, prolog and epilog are not included.

Using inline assembler code, you may utilize this functionality to create your own prolog/epilog code sequences. Writing virtual device drivers makes good use of naked functions. Keep in mind that the x64 platform does not support the naked property; it is only valid on x86 and ARM.

Syntax

Naked functions must utilize extended attribute syntax and the __declspec keyword as the naked attribute only affects a function's declaration and is not a type modifier.

Even if a function is tagged with the __force inline keyword and the naked attribute, the compiler cannot create an inline function for that function.

If the naked attribute is used on anything other than the definition of a non-member method, the compiler throws an error.

Examples

Only the nature of the prolog and epilog sequences generated by the compiler is impacted by the naked property.

It has no impact on the code created to invoke these functions. Thus, function pointers cannot contain the naked property since it is not regarded as a component of the type of the function. Additionally, a data definition cannot use the naked property.

Rules and Limitations

Following are the rules and limitations of Naked Function Call in C++:

  • The return keyword cannot be used here in this type of function call
  • _alloca function cannot be used in this type of function calls
  • Initialized local variables are not allowed at function scope to guarantee that no initialization code for local variables enters before the prolog sequence. Particularly, function scope does not allow the definition of C++ objects. A nested scope could, however, include initialized data.
  • Naked Function Calls in C++ must unwind over the stack frame. So, C++ exception handling constructs and structured exception handling are not allowed.
  • Naked Function Calls in C++ must unwind over the stack frame. So, setjmp cannot be used for Naked Function Calls in C++.
  • Every time one of the register parameters for __fastcall bare functions is referenced in C/C++ code, the prolog code should save the value of that register onto the stack location for that variable.
  • If the Naked function call is in lexical scope, C++ class objects cannot be declared. But you are still allowed to define objects in nested blocks.
  • Although it is not advised, the frame pointer optimization (the / Oy compiler option) is automatically suppressed for a naked function.
  • When Naked Function Call building is done with / clr, the naked keyword can be ignored.

Example

Ideas to Keep in Mind While Writing Prolog/Epilog Code

It's crucial to comprehend the structure of the stack frame before creating your own prolog and epilog code sequences. Understanding how to utilize the __LOCAL SIZE symbol is also helpful.

Stack Frame Layout

This illustration displays typical prolog code that might be used in a 32-bit function:

Example:

The "registers" variable is a placeholder for the list of registers that should be saved on the stack, and the "localbytes" variable indicates how many bytes are required on the stack for local variables. You can put any other pertinent data on the stack after pushing the registers. The relevant epilog code is as follows:

Epilog Code

The stack always becomes smaller (from high to low memory addresses). The pushed value of ebp is where the base pointer (ebp) points. At ebp-4, the residents' region starts. Calculate an offset from ebp by deducting the right amount from ebp in order to access local variables.

LOCAL SIZE

For usage in the inline assembler block of the function prolog code, the compiler supplies a symbol called __LOCAL SIZE. In custom prolog code, this symbol is used to allocate space for local variables on the stack frame.

The value of __LOCAL SIZE is set by the compiler. The sum of all user-defined local variables and compiler-generated temporary variables makes up its value. Only as an instantaneous operand, __LOCAL SIZE cannot be utilized in an expression. You are not permitted to alter or reinterpret the meaning of this symbol. For instance:

The __LOCAL SIZE symbol is used in the prolog sequence of the naked function that employs unique prolog and epilog sequences as follows:

Example

This is all about Naked Function Calls in C++ Language.