







Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
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
1 / 13
This page cannot be seen from the preview
Don't miss anything!








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:
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.
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
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.
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 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];
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.
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.
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.
There is one very important use for 'static'. Consider this bit of code.
char * func(void);
main() { char *Text1; Text1 = func(); }
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.
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.
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:
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 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.
In the following section, we will discuss the scope and lifetime of variables.
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."
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.
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.
Consider the following examples:
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.
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.
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[]) { … … … }
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.