数组名等价于首元素地址

00401292 <_main>:
int main(int argc, char **argv)
{
  401292:	55                   	push   %ebp
  401293:	89 e5                	mov    %esp,%ebp
  401295:	83 ec 18             	sub    $0x18,%esp
  401298:	83 e4 f0             	and    $0xfffffff0,%esp
  40129b:	b8 00 00 00 00       	mov    $0x0,%eax
  4012a0:	89 45 f4             	mov    %eax,0xfffffff4(%ebp)
  4012a3:	8b 45 f4             	mov    0xfffffff4(%ebp),%eax
  4012a6:	e8 85 04 00 00       	call   401730 <___chkstk>
  4012ab:	e8 f0 00 00 00       	call   4013a0 <___main>
    char buf[] = "a";   
  4012b0:	0f b7 05 90 12 40 00 	movzwl 0x401290,%eax
  4012b7:	66 89 45 fe          	mov    %ax,0xfffffffe(%ebp)
    char *p = 0;
  4012bb:	c7 45 f8 00 00 00 00 	movl   $0x0,0xfffffff8(%ebp)
    return 0;
  4012c2:	b8 00 00 00 00       	mov    $0x0,%eax
}
  4012c7:	c9                   	leave  
  4012c8:	c3                   	ret    
  4012c9:	90                   	nop    
数组名buf 映射为 0xfffffffe(%ebp) ,指针p    映射为  0xfffffff8(%ebp) 没什么区别啊!
可是你可以 p = buf; 而不能 buf = p; 为什么?

首先明确一点 指针是基本数据类型, 数组是一种线性数据结构,
不能直接buf = p,这是C编译器实现的, 他会类型检查,要把一个4字节大小的指针数据(32位系统)放到一个不一定是4字节空间的区域,编译器无法转换,所以报error;
而数组名做右值时,隐式类型转换为指针,赋值后,左边的变量 == 其首元素地址;

怎么 让 buf = p; 绕过类型检查就行,但意义完全变了,
这种赋值, 是让buf首元素地址的内容 = p指针变量的值

  下面代码 小端序输出 "BA"

#include <stdio.h>
int main(int argc, char **argv)
{
  401292:	55                   	push   %ebp
  401293:	89 e5                	mov    %esp,%ebp
  401295:	83 ec 18             	sub    $0x18,%esp
  401298:	83 e4 f0             	and    $0xfffffff0,%esp
  40129b:	b8 00 00 00 00       	mov    $0x0,%eax
  4012a0:	89 45 f4             	mov    %eax,0xfffffff4(%ebp)
  4012a3:	8b 45 f4             	mov    0xfffffff4(%ebp),%eax
  4012a6:	e8 a5 04 00 00       	call   401750 <___chkstk>
  4012ab:	e8 10 01 00 00       	call   4013c0 <___main>
    char buf[] = "a";   
  4012b0:	0f b7 05 90 12 40 00 	movzwl 0x401290,%eax
  4012b7:	66 89 45 fe          	mov    %ax,0xfffffffe(%ebp)
    char *p = 0x100 * 'A' + 'B';
  4012bb:	c7 45 f8 42 41 00 00 	movl   $0x4142,0xfffffff8(%ebp)

    *(char **)&buf = p;
  4012c2:	8b 45 f8             	mov    0xfffffff8(%ebp),%eax
  4012c5:	89 45 fe             	mov    %eax,0xfffffffe(%ebp)
    putchar(buf[0]);
  4012c8:	0f be 45 fe          	movsbl 0xfffffffe(%ebp),%eax
  4012cc:	89 04 24             	mov    %eax,(%esp,1)
  4012cf:	e8 1c 05 00 00       	call   4017f0 <_putchar>
    putchar(buf[1]);
  4012d4:	0f be 45 ff          	movsbl 0xffffffff(%ebp),%eax
  4012d8:	89 04 24             	mov    %eax,(%esp,1)
  4012db:	e8 10 05 00 00       	call   4017f0 <_putchar>
    return 0;
  4012e0:	b8 00 00 00 00       	mov    $0x0,%eax
}
  4012e5:	c9                   	leave  
  4012e6:	c3                   	ret  

 

posted @ 2012-11-23 23:44  庄庄庄  阅读(480)  评论(0编辑  收藏  举报