Calling Convention-Windows Programming-Lecture Notes, Study notes of Windows Programming

This lecture handout is for Windows Programming course. It was provided by Prof. Jaimini Chinmay at Ambedkar University, Delhi. It includes: History, Brief, Win32, Dos, Box, Window, Multitask, Coperative, Preemptive, Version, Operating

Typology: Study notes

2011/2012

Uploaded on 08/07/2012

anishay
anishay 🇮🇳

4.2

(25)

118 documents

1 / 13

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Calling Conventions, Storage classes and Variable Scope 2
Calling Convention
To call a function, you must often pass parameters to it. There are plenty of ways how
this can be done. You either pass the parameters on the calling stack (place where the
processor also places the temporary pointer to the code following the call, so it knows
where to continue after the call was done), or you pass some of them in registers. Floating
point values can also be passed on the stack of the coprocessor.
Calling conventions rule how parameters will be passed (stack only or registers), in
which order they will be passed (from left to right, i.e. in the same order as they appear in
source code, or the other way around), and which code will clean the stack after use, if
necessary. There are a lot of possible combinations:
pascal, the original calling convention for old Pascal programs;
register, the current default calling convention in Delphi;
cdecl, the standard calling convention for C and C++ code;
stdcall, the default cross-language calling convention on 32-bit Windows;
safecall, a special case of stdcall, which can be ignored for now.
Difference between __stdcall and __cdecl calling convention
cdecl and __stdcall just tells the compiler whether the called function or the calling
function cleans up the stack. In __stdcall calling convention, the called function cleans up
the stack when it is about to return. So if it is called in a bunch of different places, all of
those calls do not need to extra code to clean up the stack after the function call.
In __cdecl calling convention, it is the caller function that is responsible for cleaning the
stack, so every function call must also need to include extra code to clean up the stack
after the function call.
Default Calling Convention for C programmes
The __cdecl is the default calling convention for C programs. In this calling convention,
the stack is cleaned up by the caller. The __cdecl calling convention creates larger
executables than __stdcall, because it requires each function call to include stack cleanup
code.
The following list shows the implementation of _cdecl calling convention.
Element Implementation
Argument-passing order Right to left
docsity.com
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Partial preview of the text

Download Calling Convention-Windows Programming-Lecture Notes and more Study notes Windows Programming in PDF only on Docsity!

Calling Convention

To call a function, you must often pass parameters to it. There are plenty of ways how this can be done. You either pass the parameters on the calling stack (place where the processor also places the temporary pointer to the code following the call, so it knows where to continue after the call was done), or you pass some of them in registers. Floating point values can also be passed on the stack of the coprocessor.

Calling conventions rule how parameters will be passed (stack only or registers), in which order they will be passed (from left to right, i.e. in the same order as they appear in source code, or the other way around), and which code will clean the stack after use, if necessary. There are a lot of possible combinations:

  • pascal , the original calling convention for old Pascal programs;
  • register , the current default calling convention in Delphi;
  • cdecl , the standard calling convention for C and C++ code;
  • stdcall , the default cross-language calling convention on 32-bit Windows;
  • safecall , a special case of stdcall, which can be ignored for now.

Difference between __stdcall and __cdecl calling convention

cdecl and __stdcall just tells the compiler whether the called function or the calling function cleans up the stack. In __stdcall calling convention, the called function cleans up the stack when it is about to return. So if it is called in a bunch of different places, all of those calls do not need to extra code to clean up the stack after the function call.

In __cdecl calling convention, it is the caller function that is responsible for cleaning the stack, so every function call must also need to include extra code to clean up the stack after the function call.

Default Calling Convention for C programmes

The __cdecl is the default calling convention for C programs. In this calling convention, the stack is cleaned up by the caller. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code.

The following list shows the implementation of _cdecl calling convention.

Element Implementation

Argument-passing order Right to left

Stack-maintenance responsibility Calling function pops the arguments from the stack

Name-decoration convention Underscore character (_) is prefixed to names

Case-translation convention No case translation performed

Default Calling Convention for Windows Programmes

The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack

Functions that use this calling convention require a function prototype.

return-type __stdcall function-name [( argument-list )]

The following list shows the implementation of this calling convention.

Element Implementation

Argument-passing order Right to left.

Argument-passing convention By value, unless a pointer or reference type is passed.

Stack-maintenance responsibility Called function pops its own arguments from the stack.

Name-decoration convention An underscore (_) is prefixed to the name. The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list. Therefore, the function declared as int func( int a, double b ) is decorated as follows: _func@

Case-translation convention None

Objects with the auto storage class specifier have automatic storage duration. Each time a block is entered; storage for auto objects defined in that block is made available. When the block is exited, the objects are no longer available for use.

If an auto object is defined within a function that is recursively invoked, memory is allocated for the object at each invocation of the block.

2. Register - Storage Class

Register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and cant have the unary '&' operator applied to it (as it does not have a memory location). { register int Miles; }

Register should only be used for variables that require quick access - such as counters. It should also be noted that defining 'register' does not mean that the variable will be stored in a register. It means that it MIGHT be stored in a register - depending on hardware and implementation restrictions.

  • The register storage class specifier indicates to the compiler that a heavily used variable (such as a loop control variable) within a block scope data definition or a parameter declaration should be allocated a register to minimize access time.
  • It is equivalent to the auto storage class except that the compiler places the object, if possible, into a machine register for faster access.
  • An object having the register storage class specifier must be defined within a block or declared as a parameter to a function.

The following example lines define automatic storage duration objects using the register storage class specifier:

register int score1 = 0, score2 = 0; register unsigned char code = 'A'; register int *element = &order[0];

Initialization

You can initialize any register object except parameters. If you do not initialize an automatic object, its value is indeterminate. If you provide an initial value, the expression representing the initial value can be any valid C expression. For structure and union members, the initial value must be a valid constant expression if an initializer list is used.

The object is then set to that initial value each time the program block that contains the object's definition is entered.

  • Objects with the register storage class specifier have automatic storage duration. Each time a block is entered, storage for register objects defined in that block are made available. When the block is exited, the objects are no longer available for use.
  • If a register object is defined within a function that is recursively invoked, the memory is allocated for the variable at each invocation of the block.

3. Static Storage Class

Static is the default storage class for global variables. An object having the static storage class specifier can be defined within a block or at file scope. If the definition occurs within a block, the object has no linkage. If the definition occurs at file scope, the object has internal linkage.

Example:

Two variables below (count and road) both have a static storage class. Static variables can be 'seen' within all functions in this source file. At link time, the static variables defined here will not be seen by the object modules that are brought in.

static int Count; int Road; main() { printf("%d\n", Count); printf("%d\n", Road); }

'static' can also be defined within a function! If this is done the variable is initialized at run time but is not re initialized when the function is called.

Example:

There is one very important use for 'static'. Consider this bit of code.

char * func(void);

main() { char *Text1; Text1 = func(); }

File Scope Usage

The static storage class specifier causes the variable to be visible only in the file where it is declared. Files, therefore, cannot access file scope static variables declared in other files.

Restrictions We cannot declare a static function at block scope.

4. Extern Storage Class

Extern defines a global variable that is visible to all object modules. When you use 'extern' the variable cannot be initialized as all it does is to point the variable name at a storage location that has been previously defined.

With extern keyword, we are actually pointing to such a variable that is already been defined in some other file.

Source 1 Source 2


extern int count; int count=5;

write() main() { { printf("count is %d\n", count); write(); } } Count in 'source 1' will have a value of 5. If source 1 changes the value of count - source 2 will see the new value

The extern storage class specifier lets you declare objects and functions that several source files can use. All object declarations that occur outside a function and that do not contain a storage class specifier declare identifiers with external linkage. All function definitions that do not specify a storage class define functions with external linkage.

An extern variable, function definition, or declaration also makes the described variable or function usable by the succeeding part of the current source file. This declaration does not replace the definition. The declaration is used to describe the variable that is externally defined.

If a declaration for an identifier already exists at file scope, any extern declaration of the same identifier found within a block refers to that same object. If no other declaration for the identifier exists at file scope, the identifier has external linkage.

An extern declaration can appear outside a function or at the beginning of a block. If the declaration describes a function or appears outside a function and describes an object with external linkage, the keyword extern is optional.

If we do not specify a storage class specifier, the function has external linkage.

Initialization

We can initialize any object with the extern storage class specifier at file scope. Similarly, we can also initialize an extern object with an initializer that must either:

  • Appear as part of the definition and the initial value must be described by a constant expression. OR
  • Reduce to the address of a previously declared object with static storage duration. This object may be modified by adding or subtracting an integral constant expression.

If we do not explicitly initialize an extern variable, its initial value is zero of the appropriate type. Initialization of an extern object is completed by the time the program starts running.

Storage Allocation

Storage is allocated at compile time for extern variables that are initialized. Un- initialized variables are mapped at compile time and initialized to 0 (zero) at load time. This storage is freed when the program finishes running.

Scope, Initialization and Lifetime of Variable

In the following section, we will discuss the scope and lifetime of variables.

Example:

Consider the example below:

int main () { float temp = 1.1; int a; int b; printf ("Value for a and b [int]: ");

An example of a stack is the pop-up mechanism that holds trays or plates in a cafeteria.

The last plate placed on the stack (insertion) is the first plate off the stack (deletion). A

stack is sometimes called a Last-In, First-Out or LIFO data structure. Stacks have

many uses in computing. They are used in solving such diverse problems as "evaluating

an expression" to "traversing a maze."

Application of Stacks

A stack data structure is used when subprograms are called. The system must remember

where to return after the called subprogram has executed. It must remember the contents

of all local variables before control was transferred to the called subprogram. The return

from a subprogram is to the instruction following the call that originally transferred

control to the subprogram. Therefore, the return address and the local variables of the

calling subprogram must be stored in a designated area in memory. For example,

suppose function A has control and calls B which calls C which calls D. While D is

executing, the return stack might look like this:

The first "return" would return (from D) to the return address in Function C and the

return stack would then look like:

The last function called is the first one completed. Function C cannot finish execution

until Function D has finished execution. The sequence in which these functions are

executed is last-in, first-out. Therefore, a stack is the logical data structure to use for

storing return addresses and local variables during subprogram invocations. You can see

that the "stack" keeps the return addresses in the exact order necessary to reverse the

steps of the forward chain of control as A calls B, B calls C, C calls D.

Const Access Modifier

The const keyword is used to create a read only variable. Once initialized, the value of the variable cannot be changed but can be used just like any other variable.

const int i = 10; // “i ” cannot be changed in the programme.

Constant Variables

Consider the following examples:

  • Constant pointer to variable data:

char * const ptr = buff. // constant pointer to variable data *ptr = ‘a’; ptr = buff2; // it will be an error

since we have declared ptr as a “constant pointer to variable data”, so we can change the contents of the place where ptr is pointing at, i.e. data but being a constant variable, the ptr value i.e. the address it contains cannot be modified.

  • Variable pointer to Constant data:

const char * ptr = buff. //variable pointer to constant data *ptr = ‘a’; // it will be an error ptr = buf2;

Here, ptr has been declared as “variable pointer to constant data”. In this case, the data to which the ptr is pointing to remains constant and cannot be modified after initialization. The contents of ptr (address) are variable and we can change the contents of ptr.

Command Line Arguments

C provides a fairly simple mechanism for retrieving command line parameters entered by the user. It passes an argv parameter to the main function in the program.

int main(int argc, char *argv[]) { … … … }

Summary

The calling conventions tells us in which order the parameters will be passed in a function and whether the calling function or the called function is responsible for the cleaning of the stack.

The default calling convention for C programs is __cdecl and in this convention, the caller is responsible for cleaning the stack after the function call.

Similarly, the default calling convention for the windows programs is __stdcall. Here the called function itself has to do the stack clean up and so no extra code is required for stack clean up with each function call. It is very obvious that the __cdecl calling convention creates larger executables because it requires each function call to include the clean up code.

Storage classes are used to describe the scope and visibility of the variables and functions. The common storage classes discussed above are auto, register, static, and extern etc.

In the lifetime of variables, we have discussed that each { } block creates a new scope. Variables declared and initialized in a scope are deleted when execution leaves that scope

The const keyword is used to create a read only variable. Thus constant variables are not allowed to be modified after initialization.

Command line arguments provide an easy way to pass some parameters to the programme in the main function when the programme execution starts. When using an executable that requires startup arguments to debug, you can type these arguments at the command line, or from within the development environment.