标签归档:程序的机器级表示

linux c 指针运算 指针表示法


c允许对指针进行运算,而计算出来的值会根据该指针引用的数据类型的大小进行调整。

也就是说,如果p是一个指向类型T的数据的指针,p的值为xp,表达式p+i的值为xp+L*i,这里L是一个数据类型T的大小。
单操作数的操作符&和*可以产生指针和间接引用指针。也就是,对于一个表示某个对象的表达式Expr,&Expr表示一个地址。对于一个地址表达式AddrExpr,*AddrExpr表示该地址中的值。
因此,表达式Expr *&Expr是相同的,等价的。
可以对数组和指针应用数组下标操作,如数组引用A[i]和表达式*(A+i)是一样的.它计算第i个数组元素的地址,然后访问这个存储器的位置。


例:
整数数组E的起始地址和整数索引i分别存放在寄存器%edx和%ecx,结果存放在%eax中。

数据分配和访问原理

在c语言中数组是一种将标量型数据集聚成更大数据类型的方式之一。
在c语言中实现数组的方式非常简单,因此很容易翻译成机器代码。c语言相对于其它语言不同的地方在于可以对数组中元素产生指针,并对这些指针进行运算。这些运算可以翻译成地址进行运算。


一个数据类型T,长度为N的数组

T Array[N];

首先,它在存储器中分配了M=N*sizeof(T)个字节的连续区域,假如我们用xa来表示起始位置,然后再引入数组标识符Array,Array可以用来作为指向数组开头的指针。这个指针的值xa,可以用0~T-1之间的整数索引来访问数组。数组元素i的存放位置为xa+N*i。


例: 有以下 数组申明
char A[12];
char *B[12];
double C[6];
double *D[5];
数组在计算机中的存储分配如下所示:

数组

元素大小

总大小

起始地址

元素i所在位置
A

1

12

xA

xA+i
B

4

32

xB

xB+i
C

8

48

xC

xC+i
D

4

20

xD

xD+i

数组A由12个单字节组成(char)元素组成,数组C由6个双精度浮点值组成,每个值需要8个字节组成,B和D为指针数组,所以B和D每个元素都是4个字节。

数据访问原理:
例: 假设E是一个整数数组,当我们想计算E[i],首先E的地址存放在寄存器 %edx中,而i存放在寄存器%ecx中,那么指令
movl (%edx,%ecx,4),%eax
会执行地址计算xE+4i,在这个位置执行读操作,然后把数据放入寄存器%eax中 。