There three type of address order in computer
1. address order for variables
there maybe many varaibles in the program, and whose address is higher and whose is lower?
general thinking it should increase by the sequence the variant is defined.
However usually we define variable in the stack, so the earlier defined variant has higher address.
for example
char first; char second; first's address is higher than second's.
int main(){
int i;
int j;
int k;
printf("%x\n",&i);
printf("%x\n",&j);
printf("%x\n",&k);
}
and the result will be
22cd64
22cd60
22cd5c
2.address in one variable
usually a variable need more than one byte to storage, for example in 32bit pc, int need 4 bytes, short needs 2 bytes
and how are they storaged in the pc?
here is Endianness.There are two Endianness, Little Endian and Big Endian
a. low byte
If one variable occupy more than one byte, there must be low byte and high byte for the variable.
for example, int a = 0x3233, the low byte is 33 andthe high byte is 32.
char p = "abcd", the low byte is 'a', and high byte is 'd'.
(is there some regular rules for distinguishing which byte is high and which byte is low, inside one variable? i am still finding it.
but as i know the int and char is the same as i told above, the long short is the same as int)
b. LittleEdian and Big Endian
Little Endian means low byte stored in the low address
Big Endian means low byte stored in the high address.
assuming int a =0x01020304, was in 0x00000000(of course impossible in real program, just for ex), and it occupis four bytes as below.
0x00000003 0x0000002 0x00000001 0x00000000
and it's byte from low to high is 04,03,02,01,
so in Little Endian, it will be stored as
0x00000003(01) 0x0000002(02) 0x00000001(03) 0x00000000(04)
and in Big Endian, it will be stored as
0x00000003(04) 0x0000002(03) 0x00000001(02) 0x00000000(01)
Since the ibm pc storage variable in Little Endian, we can write a program to test it.
c. example
int main(){
int a = 0x01020304;
char *p = (char*)&a;
printf("%x\n",*p);
}
as we talked above, as we assinged p to a's address, p will be pointed to the lowest address of a.
in Little Endian, that will be the lowest byte of teh variable , that 04.
we run it , and the result shows 4.
d.pointer's address
And there is one thing we have to mention.
No matter what the pointer's type is, it actually points just one byte in the memory.
No matter how big a type or a structure will be, so long as we assign the address of it's instance to a point,
the point will actually be assiged to the lowest byte address of the variable.
int main(){
int a = 0x01020304;
char *p = (char*)&a;
printf("%x\n",p);
int *pi = (int*)&a;
printf("%x\n",p);
short *ps = (short*)&a;
printf("%x\n",ps);
}
all the address output is the same, which will
be the lowest byte's address of a. (04, as we tested before)
3. bit order in byte
bit order, from right to left that is from lower to higher. 0x32 will be 0x01010010
actually there is no need to talk about it.
we just mentioned it to distinguishing the two types above.
4. supplement, Bytes align.
We have met it too much before, usually in caculation a structure's size.
if some type is less than a machine's word-length,it will still be assigned a word-leng's size.
But, how is the variable stored in one word?from the left to right , or from the right to left?
int main(){
int i;
char c;
int j;
short s;
int k;
printf("%x\n",&i);
printf("%x\n",&c);
printf("%x\n",&j);
printf("%x\n",&s);
printf("%x\n",&k);
}
assuming i's address will be 0x22cd64
and ofcource j's will be 22cd5c(0x22cd64-8) and k's will be 22cd54(0x22cd64-8)
but what will be c's address, 0x22cd63,0x22cd62,0x22cd61 or 0x22cd61?
and what will be s's address 0x22cd5aor 0x22cd58?
as i tested the result was showd as below.
22cd6422cd63
22cd5c
22cd5a
22cd54
it seems it is stored in a machine byte as higher as possible. (However, I havn't found out why.)
there is one program to test if the mechine is Big Endian for Little Endian
#include <stdio.h>
int main()
{
union
{
short inum;
char c[sizeof(short)];
}un;
un.inum=0x0102;
if(sizeof(short)!=2)
{
printf("sizeof(short)=%d\n",sizeof(short));
return 0;
}
if(un.c[0]==1 && un.c[1]==2)
printf("big_endian.\n");
else if(un.c[0]==2 && un.c[1]==1)
printf("little_endian.\n");
else
printf("unknown.\n");
return 0;
}