C Programming - Byte Order

Little Endian Byte Order:
"Little Endian" means that the low-order byte of the number is stored in memory at the lowest address, and the high-order byte at the highest address.

eg. long int i = 0x12345678; /* assuming long int has 4 bytes */

0x8000490: 0x78
0x8000491: 0x56
0x8000492: 0x34
0x8000493: 0x12

Big Endian Byte Order:
"Big Endian" means that the high-order byte of the number is stored in memory at the lowest address, and the low-order byte at the highest address.

eg. long int i = 0x12345678;

0x8000490: 0x12
0x8000491: 0x34
0x8000492: 0x56
0x8000493: 0x78

Function to find whether an architecture is Big or Little Endian:

char endian() /* 0 - Big Endian, 1 - Little Endian */
{
long i = 1;
return *((char *) &i);
}

Labels:

Posted by - at 10:34 pm | 0 comments read on

C Programming - Complicated Declaration Made Simple

Introduction

A declaration can have exactly one basic type, and it's always on the far left of the expression.

The "basic types" are augmented with "derived types", and C has three of them:

*   pointer to...

This is denoted by the familiar * character, and it should be self evident that a pointer always has to point to something.

[]   array of...

"Array of" can be undimensioned -- [] -- or dimensioned -- [10] -- but the sizes don't really play significantly into reading a declaration. We typically include the size in the description. It should be clear that arrays have to be "arrays of" something.

()   function returning...

This is usually denoted by a pair of parentheses together - () - though it's also possible to find a prototype parameter list inside. Parameters lists (if present) don't really play into reading a declaration, and we typically ignore them. We'll note that parens used to represent "function returning" are different than those used for grouping: grouping parens surround the variable name, while "function returning" parens are always on the right.

Functions are meaningless unless they return something (and we accommodate the void type by waving the hand and pretend that it's "returning" void).


A derived type always modifies something that follows, whether it be the basic type or another derived type, and to make a declaration read properly one must always include the preposition ("to", "of", "returning"). Saying "pointer" instead of "pointer to" will make your declarations fall apart.

It's possible that a type expression may have no derived types (e.g., "int i" describes "i is an int"), or it can have many. Interpreting the derived types is usually the sticking point when reading a complex declaration, but this is resolved with operator precedence in the next section.

Operator Precedence

Almost every C programmer is familiar with the operator precedence tables, which give rules that say (for instance) multiply and divide have higher precedence than ("are preformed before") addition or subtraction, and parentheses can be used to alter the grouping.

This seems natural for "normal" expressions, but the same rules do indeed apply to declarations - they are type expressions rather than computational ones.

The "array of" [] and "function returning" () type operators have higher precedence than "pointer to" *, and this leads to some fairly straightforward rules for decoding.

Always start with the variable name:

foo is ...

and always end with the basic type:

foo is ... int

The "filling in the middle" part is usually the trickier part, but it
can be summarize with this rule:

"go right when you can, go left when you must"

Working your way out from the variable name, honor the precedence rules and consume derived-type tokens to the right as far as possible without bumping into a grouping parenthesis. Then go left to the matching parenthesis.

A simple example

We'll start with a simple example:
long **foo[7]
We'll approach this systematically, focusing on just one or two small part as we develop the description in English. As we do it, we'll show the focus of our attention in red,and strike out the parts we've finished with.


long **foo [7];

Start with the variable name and end with the basic type:

foo is ... long

long ** foo[7];

At this point, the variable name is touching two derived types:
"array of 7" and "pointer to", and the rule is to go right when you can,
so in this case we consume the "array of 7"

foo is
array of 7
...
long


long ** foo[7];

Now we've gone as far right as possible, so the innermost part is only touching the "pointer to" - consume it.


foo is
array of 7
pointer to
...
long

long**foo[7];

The innermost part is now only touching a "pointer to", so consume it also.


foo is
array of 7
pointer to
pointer to
long


Labels:

Posted by - at 1:22 am | 1 comments read on

C Programming - One amoung the Two-> x = x == a ? b : a;

x can have only values a or b, we want to assign x a value otherthan the current one.

x ^= a ^ b

Labels:

Posted by - at 1:13 am | 0 comments read on

C Programming - Exchanging Corresponding fields of integer

Exchange the contents of the variable x and y wherever the mask bit mi=1

x^=y
y^=(x&m)
x^=y

Labels:

Posted by - at 11:39 pm | 0 comments read on

C Programming - Turn OFF Right Most ON Bit

x & (x - 1)

AlSo UsEd To FiNd If x Is A pOwEr Of 2

Labels:

Posted by - at 9:50 pm | 0 comments read on

C Programming - Rounding Up

An unsigned integer x can be rounded up to the next greater multiple of 8 with either of

(x + 7) & -8
x + (-x & 7)

Labels:

Posted by - at 9:49 pm | 0 comments read on

C Programming - Power of Two Minus One

To test if an unsigned integer is of the form 2n - 1

x&(x+1)

Labels:

Posted by - at 9:49 pm | 1 comments read on

C Programming - Vintage XOR Swap

#define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))

Will that work in case of SWAP(a[i], a[j]) when i == j ?

Labels:

Posted by - at 9:48 pm | 0 comments read on

C Programming - Skip

This will give desired output for Windows/Linux x86 Platform with gcc and visual studio 6.0 compilers

int f()
{
int i;
int *j = &i;
*(j+2) += 7;
}

int main()
{
int i=10;
f();
i = 20;
printf("i=%d\n",i);
}

Here the function f() manupulates the return address i.e. where it was supposed to return to main() because the return address(EIP) is pushed, during a function call, into the stack. We computed that, to skip the instruction i=20, we need to increment the EIP by 7 such that the resulting address will point to printf statement.

Labels:

Posted by - at 9:48 pm | 0 comments read on

C Programming - Sign Of An Integer

using Bitwise operators only....

int num;
num >> (sizeof(int) * 8 - 1) /* -1 means negative */

Labels:

Posted by - at 9:47 pm | 0 comments read on

C Programming - RunTime Compile

I tried this on Linux machine like redhat and debian

/* input.c */

#include "/dev/tty"

/* EOF */

$>gcc input.c

Labels:

Posted by - at 9:47 pm | 0 comments read on

C Programming - Prints Anything

printf(&1["\017%six\010\000"],"fun" + 1["have"] - 0x60);

from Bell Labs is still regarded as one of the most powerful, versatile, and flexible operating systems (OS) in the computer world.


int printf( const char *format, . . . )

Labels:

Posted by - at 9:45 pm | 0 comments read on

Archives

  • May 2011
  • February 2009
  • December 2008
  • November 2008
  • October 2008
  • August 2008
  • April 2008
  • December 2007
  • November 2007
  • January 2007
  • December 2006
  • October 2006
  • September 2006
  • June 2006
  • May 2006
  • April 2006
  • March 2006
  • February 2006
  • January 2006
  • December 2005
  • November 2005
  • October 2005

Links