Archive for the 'Tutorials' Category

Pointers

Pointers are very common and powerfull parts of programming languages such as C and C++. If you have never encountered pointers before (you are probably from the world of Java or .NET) you may ask “Why?”. Well, if you know an object-oriented language you may notice how you can use the pointers to simulate behaviours similar to reference types. Like reference types pointers “point” to a specific object, but through its address in memory.

In C and C++ you declare and use a pointer this way:


int a = 20;
int *p = &a;

printf("%d", p);

*p = 30; //Manipulating the value (*p)

printf("%d", *p); // Will print 30 to the console.

printf("%d", p); // Will print the address which the pointer points to (p)

I will now explain this fairly simple piece of code. We declare an integer (a) and give it the value 20. Nothing strange so far. Then we declare a pointer to integer variable. int* means pointer to integer. It is being initialized with the address of the integer (a) we declared. The address operator is & (read as address of). Later we starts to manipulate the memory through the pointer. Just notice the difference between *p and p (commented in the code). As it is shown both p and a are referencing the same memory. The power of pointers! But when you are getting more experienced and you are working with more advanced stuff you have to take responsibility. That will I talk about later in this blogpost.

A native string type does not exist in C, but you can simulate one with arrays or pointers. Yes, pointers. Take a look at the following example where a pointer to a character is initated with a string.


char *str;
str = "Hello, World!";

//This is similar to:
char[] strAr = "Hello, Second World!";

As I said before it is almost like OOP with reference types. You can point to primitive types and structures, and even functions. Function pointers are similar to delegates in C#, though delegates are type-safe and function pointers not. These are declared and initiated as in this example:


int (*Operation)(int OpA, int OpB);

static int Add(int OpA, int OpB)
{
      return OpA + OpB;
}

static int Sub(int OpA, int OpB)
{
      return OpA - OpB;
}

int Main(void)
{
      Operation = Add;
      int r1 = (*Operation)(2, 3); //5

      Operation = Sub;
      int r2 = (*Operation)(3, 2); //1

      return 0;
}

With these two types of pointers you can do a lot of cool and advanced stuff. One of the many common uses of type pointers are allocation and reallocation of memory. You do like this:


int *ptr = malloc(sizeof (int));

The argument of malloc is the size of memory you want to allocate.

Because you are allocating the memory the program cannot manage it for you. That is to say that if your program is ending you will have to reallocate the memory you have used. The memory will remain allocated if you do not do so. That makes exception handling very important in your program. The There are certain functions to reallocate or free occupied memory. The most simple are free which takes a pointer as an argument. It will automatically free the memory the pointer is referencing to.


     free(ptr);

Because of the pointers, languages like C and C++ are good for system- and hardware programming. If you for instance want to write a driver for a specific device, that is manipulating the hardware, you use pointers because they are able to manipulate memory and through it the basic parts of the computer. Pointers make C nearly as powerfull as assembler (machine language), as close to the hardware you can get.

This was a short introduction to pointers. There are many of ways of using them. It takes a lot of practice to master them without messing stuff up although they are easy to declare.

I just want to add that C# does have pointers although they are not common to use. They are mostly used in P/Invoke (platform invocation) to unmanaged native code in i.e. the Windows API. These parts are abstracted away by the managed OOP classes in the .NET Framework. You can still do some pretty advanced stuff with pointers but you do not need to, or rather you are encouraged not to use them, because they considered are unsafe. They are thereby against the principles of the CLI (Common Language Infrastructure). Java does currently not have pointers (no instructions for them). Maybe they will add support in the future, but who knows.

Thanks for reading.

Common Intermediate Language

Common Intermediate Language, simply known as CIL, IL or MSIL (among the legacy coders). This is not to be confused with C Intermediate Language which is also abbreviated as CIL. CIL is a stack-based high-level assembly language which is used as an intermediate language by virtual machines such as the CLR (Common Language Runtime) and the Mono Runtime. It is because it has a fairly simple syntax that can easily be translated into native machine code. As a part of the Common Language Infrastructure (CLI, a standard developed by Microsoft) it is the most significant piece of the .NET Framework, among others. Compilers which are written for the specific frameworks support the CLI standard and are translated to CIL. This can be done entirely or partially, like C++/CLI (which can mix it with native code). Because of that they can interop with other programs written in other CLI languages through the virtual machine. CIL is cross-platform and can be be executed on different machine architectures without being modificated or recompiled. The only thing that is needed is an implementation of the virtual machine targeting the specific processor and operating system. CIL is also, in many aspects, similar to Java bytecode which is executed by the Java Virtual Machine (JVM).

CIL is stack-based, in difference to many native machine languages that are register-based. This means that everytime you want to manipulate an object (a type or an unit of code) you put it on the stack and call an op code (language instruction) that is performing an operation, i.g. adding two values. Thereby adding the two objects (Int32 or simply 32-bit integers) on the top of the stack and leaving the sum of those. The stack should be empty at the end of runtime. See the example.

IL:

ldc.i4.3 //Loads a constant in the stack
ldc.i4.2
add

Stack:

2 //Int32
3 //Int32

After the last operation (add) this will remain on the stack:

5 //Int32

If you had only one object on the stack and performed the add operation you would get a stack underflow.
The opposite is stack overflow that is caused by objects remaining on the stack in the end of the program. These errors are often caused by bugged compilers.

Some common op codes are:

ldstr "Kazoom" //Puts a string on the stack
ldarg.0 //Loads the method argument at the index 0 and puts it on the stack
ldc.i4.29 //Puts an integer, 29, on the stack
ldloca.s lcal //Loads a local (name lcal) an places it on top of the stack
call //Used when calling a method
newobj //Used when instanciating an object

// Arithmic operations that pops two values from the top of the stack.
add
sub
mul
div
mod

This is the most simple part of the CIL language. Because of the object-oriented nature of CLI you are able to use some OOP approach in your programming. Many of the constructs found in the programming languages at a higher level are represented directly as IL. For instance, a class declaration looks like this:

.class public MyClass
{

}

A class can be declared as static (non-instance class) with the static attribute static.

.class public static MyStaticClass
{

}

Classes contains methods defined this way:

.method Int32 Add(Int32, Int32)
{
      //Load both arguments on the stack and add them, then return the value.
      ldarg.0
      ldarg.1
      add
      ret
}

Likewise to classes, methods can also be marked as static.

This syntax, is like the class syntax, very similar to the C style. The only difference is the IL opcodes instead of ordinary statements. Another thing you must know is that methods always ends with a return statement even though they do not seem to return any value. In reallity theres a value, void. This will the runtime engine (virtual machine) handle for you.

To make a method the entrypoint of the program you add the .entrypoint attribute inside the method body. Notice that you can only have one entrypoint in a program.

Local variables (mostly refered to as locals) are also defined as attributes inside a method.

.locals init (
      [0] string str1
      [1] Int32 int1)

Those locals named by the compilers often have a random name consisting of letters and a number.

Because of performance there is also a .maxstack attribute which sets the maximum numbers of items on the stack. This tells the runtime engine that this method needs a stack of this size. Now is the virtual machine able to manage the amount of memory.

There are a lot of other things as well. I will not dig deeper into it because it is to much at a time. If you are familiar with a high-level language or any other stack-based and object-oriented intermediate language, like the Parrot Intermediate Language you, should understand the IL too.

Finally, this is the Hello World program in IL style. You can try to assemble it with ILASM (IL Assembler) ported with .NET Framework or Mono.

.method public static void Main() cil managed
{    
      .entrypoint    
      .maxstack 8    
      ldstr "Hello world!."    
      call void [mscorlib]System.Console::WriteLine(string)    
      ret
}

Beginning with programming

Are you a beginner or do you want to learn how to program your own applications?

You need to know the basics to master the art of programming. Don’t worry I’ll teach you. First I will introduce some terms which are important to know. You may have heard many of following words when you practiced mathematics or studied languages. Don’t be confused. It’s really not that complicated even though there are some differences.
Let’s start :)

Identfiers are names for the elements (variables and keywords) of your code.

Keywords are reserved words that are used by the language and thereby not allowed when naming your variables. There are keywords that are aliases for build-in types.

Variables are used as in mathematics. They hold a value of a special type. You may change this value during runtime (when running your program) as you do in mathematics. Most of the program languages have variables bound to a special type. So you can’t change the type of variables.

int MyVariable = 2;        //A variable (MyVariable) for integers which holds the value 2;

Types. If you know mathematics you probably know sets of different types of numbers (Z=Integers, N=Naturals etc.).
Well, types are like sets but still not. You declare a variable of a type and it can hold just the value that the type allows.
Some important types are integer, double, float and character.

Statements are equivalent to mathematical expressions or linguistical sentences. (Note this tutorial is written in C-like syntax and “;” is the statements terminator.)

int val = 2 * 3;     //Multiply 2 with 3 and initate the variable val with the result.

Some pre-made statements are “built in” in certain programming langauges. Most notably the usefull if and while statements.

Functions are code blocks which returns a value. It’s just like in mathematics. Of course you can send one or many values (paramters) into a function.

Procedures work like functions but doesn’t return a value.

Method is a word which is refering to both functions and procedures because of their similarities.

That’s all for now :)
We’ll take a closer look in another blogpost. So stay tuned!


Pages

Categories

RSS MSDN Highlights

  • An error has occurred; the feed is probably down. Try again later.