C指针原理(20)-C指针基础

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C指针原理(20)-C指针基础相关的知识,希望对你有一定的参考价值。

结构与malloc

? ? 结构是C语言中重要的一环,malloc是一个重要的函数,它完成了动态内存分配,用malloc分配的内存块要通过free释放。通过结构可以将不同类型的数据组合成一个整体,关于结构指针,LINUX下编程经常会运用一个技巧,这个技巧用在申请缓冲区上,可以申请不同大小的缓冲区。

首先,来看一个概念消息队列 ,一个或多个进程可向消息队列写入消息,而一个或多个进程可从消息队列中读取消息,Linux中的消息被描述成在内核地址空间的一个内部链表,每一个消息队列由一个IPC的标识号唯一的标识,Linux?为系统中所有的消息队列维护一个?msgque?链表,每个消息队列都在系统范围内对应唯一的键值,要获得一个消息队列的描述字,只需提供该消息队列的键值即可。

传递给队列的消息的数据类型是一个如下形式的结构,在Linux 的系统库linux/msg.h 中,它是这样定义的:

/ message buffer for msgsnd and msgrcv calls /

struct msgbuf {

long mtype; / type of message /

char mtext[1]; / message text /

};

其中,mtype成员代表消息类型,从消息队列中读取消息的一个重要依据就是消息的类型;mtext是消息内容。这个结构的精妙之处在于,mtext虽然在结构中被声明为大小为1的字符,但实际消息内容的长度可以由程序员任意定制,定制的关键在malloc函数。下面是部分代码段:

msg=(struct?msgbuf*)malloc(sizeof(struct?msgbuf)+100);//100为消息的长度,msgbuf结构只有2个成员一个成员是mytpe,另一个成员是一个字节的mtext,在结构后分配更多的空间以存放消息字符串??

完整代码(演示了公共消息队列的使用)为:

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#define QUE_ID 2

//使用公共消息队列,读写进程可以不同时运行。
int main(void){
    int queue_id;
    struct msgbuf *msg;
    int rc;

    //建立消息队列
    queue_id=msgget(QUE_ID,IPC_CREAT|0600);//QUE_ID为一个正整数,公共消息队列的ID
    if (queue_id==-1){
       perror("create queue error!
");
       exit(1);
    }
    printf("message %d queue created!
",queue_id);
    //创建发送消息结构
    printf("message send....
");
    msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+100);//100为消息的长度,msgbuf结构只有2个成员一个成员是mytpe,另一个成员是一个字节的mtext,在结构后分配更多的空间以存放消息字符串
    msg->mtype=1;//消息类型,正整数
    strcpy(msg->mtext,"deepfuture.iteye.com");
    //发送消息
    rc=msgsnd(queue_id,msg,100,0);
    //最后一个参数可以是是0与随后这些值(或者就是0):IPC_NOWAIT,如果消息类型没有则立即返回,函数调用失败
    //MSG_EXCEPT,当消息类型大于0时,读与消息类型不同的第一条消息
    //MSG_NOERROR,如果消息长度大于100字节则被截掉
    if (rc==-1){
       perror("msgsnd error
");
       exit(1);
    }
    free(msg);//发送完毕,释放内存
    printf("message sended!
");

    return 0;
}

?以上是发送消息,以下是接收消息

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#define QUE_ID 2

//使用公共消息队列,读写进程可以不同时运行。
int main(void){
    int queue_id;
    struct msgbuf *msg;
    int rc;

    //取得消息队列
    queue_id=msgget(QUE_ID,0);//QUE_ID为一个正整数,公共消息队列的ID,

    if (queue_id==-1){
       perror("get queue error!
");
       exit(1);
    }

    printf("message recv....
");
    msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+100);
    rc=msgrcv(queue_id,msg,101,0,0);
    if (rc==-1){
       perror("recv error
");
       exit(1);
    }
    printf("recv:%s
",msg->mtext);   

    return 0;
}

效果

[email protected]:~/private/mytest$ ./testmessnd

message 0 queue created!

message send....

message sended!

[email protected]:~/private/mytest$ ./testmesrecv

message recv....

recv:deepfuture.iteye.com

[email protected]:~/private/mytest$?

7、字符串常量?

#include?<stdio.h>

int?main(int?argc,int?**argv){

????????printf?("%s","abcdefgh"+2);

}

[email protected]:~/test1?%?cc?test3.c?-o?mytest

[email protected]:~/test1?%?./mytest

cdefgh

8、函数指针


通过如下格式来声明函数指针:

返回类型?(*函数指针变量名)(参数列表)

int?add(int?a,int?b);

int?main(void){

????????int?(*myfunc)(int?a,int?b);

????????myfunc=add;

????????int?x=myfunc(12,36);

????????printf("%d",x);

????????return?1;

}

int?add(int?a,int?b){

????????return?a+b;

}

~

[email protected]:~/test1?%?cc?test1.c?-o?mytest

[email protected]:~/test1?%?./mytest

48

8、命令行参数

打印参数个数,注意,命令本身也是一个参数,所以argc至少为1。


#include?<stdio.h>

int?main(int?argc,char?**argv){

????????printf("%d
",argc);

????????return?1;

}

~

[email protected]:~/test1?%?cc?test2.c?-o?mytest

[email protected]:~/test1?%?./mytest?12

下面没有使用argc参数,直接使用了argv参数,通过判断是否null,来决定参数列表是否结束

#include?<stdio.h>

#include?<stdlib.h>

int?main(int?argc,char?**argv){

????????while?(*++argv!=NULL)

????????????????printf("%d ",argv);

????????return?1;

}

~

[email protected]:~/test1?%?cc?test2.c?-o?mytest

[email protected]:~/test1?%?./mytest?-a

-a

[email protected]:~/test1?%?./mytest?-a?12?24

-a

12

24

通过如下格式来声明函数指针数组:

返回类型?(*函数指针变量名[])(参数列表)

下面结合函数指针数组与命令行完成一些简单的运算,通过命令行传送运算符与数字。

#include?<stdio.h>

#include?<stdlib.h>

int?add(int?a,int?b){

????????return?a+b;

}

int?sub(int?a,int?b){

????????return?a-b;

}

int?main(int?argc,char?**argv){

????????int?(*operate_func[])(int,int)={

????????????????add,sub};

????????int?myresult=0;

????????int?oper=atoi(*++argv);

????????printf?("%d
",oper);

????????int?mynum;

????????while?(*++argv!=NULL)

????????{

????????????????mynum=atoi(*argv);

????????????????printf?("%d??",mynum);

????????????????myresult=operate_func[oper](myresult,mynum);

????????}

????????printf?("
%d
",myresult);

????????return?1;

}

[email protected]:~/test1?%?cc?test2.c?-o?mytest

[email protected]:~/test1?%?./mytest?0?1?13?52


0

1??13??52

66

[email protected]:~/test1?%?./mytest?1?1?13?52

1

1??13??52

-66

[email protected]:~/test1?%

1、将C文件生成中间汇编

[email protected]:~/private/mytest$ gcc -S ?hello.c

.file "hello.c"

.section .rodata

.LC0:

.string "hello,world"

.text

.globl main

.type main, @function

main:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

subl $16, %esp

movl $.LC0, (%esp)

call puts

movl $0, (%esp)

call exit

.size main, .-main

.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

.section .note.GNU-stack,"",@progbits

2、gdb调试

[email protected]:~/private/mytest$ gcc -gstabs -o hello hello.c

hello.c: In function ‘main’:

hello.c:4: warning: incompatible implicit declaration of built-in function ‘exit’

[email protected]:~/private/mytest$ gdb

GNU gdb (GDB) 7.1-ubuntu

Copyright (C) 2010 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>;

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. ?Type "show copying"

and "show warranty" for details.

This GDB was configured as "i486-linux-gnu".

For bug reporting instructions, please see:

<http://www.gnu.org/software/gdb/bugs/>;.

(gdb) file hello

Reading symbols from /home/deepfuture/private/mytest/hello...done.

(gdb) list

1 #include <stdio.h>

2 int main(){

3 ??printf("hello,world ");

4 ??exit(0);

5 }?? ? ?

(gdb) break 3

Breakpoint 1 at 0x804841d: file hello.c, line 3.

(gdb) run

Starting program: /home/deepfuture/private/mytest/hello?

Breakpoint 1, main () at hello.c:3

3 ??printf("hello,world ");

(gdb) c

Continuing.

hello,world

Program exited normally.

(gdb) quit

3、gprof图表简档,可进行程序相关性能统计,可统计出每个函数的调用时间 和处理器时间

[email protected]:~/private/mytest$ gcc -pg -o hello hello.c

hello.c: In function ‘main’:

hello.c:4: warning: incompatible implicit declaration of built-in function ‘exit’

[email protected]:~/private/mytest$ ./hello

hello,world

[email protected]:~/private/mytest$ gprof hello>myhello.txt

[email protected]:~/private/mytest$ cat myhello.txt

Flat profile:

Each sample counts as 0.01 seconds.

?no time accumulated

??% ? cumulative ? self ? ? ? ? ? ? ?self ? ? total ? ? ? ? ??

?time ? seconds ? seconds ? ?calls ?Ts/call ?Ts/call ?name ? ?

?% ? ? ? ? the percentage of the total running time of the

time ? ? ? program used by this function.

cumulative a running sum of the number of seconds accounted

?seconds ? for by this function and those listed above it.

?self ? ? ?the number of seconds accounted for by this

seconds ? ?function alone. ?This is the major sort for this

?? ? ? ? ? listing.

calls ? ? ?the number of times this function was invoked, if

?? ? ? ? ? this function is profiled, else blank.

?self ? ? ?the average number of milliseconds spent in this

ms/call ? ?function per call, if this function is profiled,

?? else blank.

?total ? ? the average number of milliseconds spent in this

ms/call ? ?function and its descendents per call, if this?

?? function is profiled, else blank.

name ? ? ? the name of the function. ?This is the minor sort

?? ? ? ? ? for this listing. The index shows the location of

?? the function in the gprof listing. If the index is

?? in parenthesis it shows where it would appear in

?? the gprof listing if it were to be printed.

4、反汇编objdump

[email protected]:~/private/mytest$ objdump -d hello

hello: ? ? file format elf32-i386

Disassembly of section .init:

080482dc <_init>:

?80482dc: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?80482dd: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?80482df: 53 ? ? ? ? ? ? ? ? ??push ? %ebx

?80482e0: 83 ec 04 ? ? ? ? ? ??sub ? ?$0x4,%esp

?80482e3: e8 00 00 00 00 ? ? ??call ? 80482e8 <_init+0xc>

?80482e8: 5b ? ? ? ? ? ? ? ? ??pop ? ?%ebx

?80482e9: 81 c3 0c 1d 00 00 ? ?add ? ?$0x1d0c,%ebx

?80482ef: 8b 93 fc ff ff ff ? ?mov ? ?-0x4(%ebx),%edx

?80482f5: 85 d2 ? ? ? ? ? ? ? ?test ? %edx,%edx

?80482f7: 74 05 ? ? ? ? ? ? ? ?je ? ? 80482fe <_init+0x22>

?80482f9: e8 1e 00 00 00 ? ? ??call ? 804831c <[email protected]>

?80482fe: e8 ed 00 00 00 ? ? ??call ? 80483f0 <frame_dummy>

?8048303: e8 a8 01 00 00 ? ? ??call ? 80484b0 <__do_global_ctors_aux>

?8048308: 58 ? ? ? ? ? ? ? ? ??pop ? ?%eax

?8048309: 5b ? ? ? ? ? ? ? ? ??pop ? ?%ebx

?804830a: c9 ? ? ? ? ? ? ? ? ??leave ?

?804830b: c3 ? ? ? ? ? ? ? ? ??ret ? ?

Disassembly of section .plt:

0804830c <[email protected]>:

?804830c: ff 35 f8 9f 04 08 ? ?pushl ?0x8049ff8

?8048312: ff 25 fc 9f 04 08 ? ?jmp ? ?*0x8049ffc

?8048318: 00 00 ? ? ? ? ? ? ? ?add ? ?%al,(%eax)

...

0804831c <[email protected]>:

?804831c: ff 25 00 a0 04 08 ? ?jmp ? ?*0x804a000

?8048322: 68 00 00 00 00 ? ? ??push ? $0x0

?8048327: e9 e0 ff ff ff ? ? ??jmp ? ?804830c <_init+0x30>

0804832c <[email protected]>:

?804832c: ff 25 04 a0 04 08 ? ?jmp ? ?*0x804a004

?8048332: 68 08 00 00 00 ? ? ??push ? $0x8

?8048337: e9 d0 ff ff ff ? ? ??jmp ? ?804830c <_init+0x30>

0804833c <[email protected]>:

?804833c: ff 25 08 a0 04 08 ? ?jmp ? ?*0x804a008

?8048342: 68 10 00 00 00 ? ? ??push ? $0x10

?8048347: e9 c0 ff ff ff ? ? ??jmp ? ?804830c <_init+0x30>

0804834c <[email protected]>:

?804834c: ff 25 0c a0 04 08 ? ?jmp ? ?*0x804a00c

?8048352: 68 18 00 00 00 ? ? ??push ? $0x18

?8048357: e9 b0 ff ff ff ? ? ??jmp ? ?804830c <_init+0x30>

Disassembly of section .text:

08048360 <_start>:

?8048360: 31 ed ? ? ? ? ? ? ? ?xor ? ?%ebp,%ebp

?8048362: 5e ? ? ? ? ? ? ? ? ??pop ? ?%esi

?8048363: 89 e1 ? ? ? ? ? ? ? ?mov ? ?%esp,%ecx

?8048365: 83 e4 f0 ? ? ? ? ? ??and ? ?$0xfffffff0,%esp

?8048368: 50 ? ? ? ? ? ? ? ? ??push ? %eax

?8048369: 54 ? ? ? ? ? ? ? ? ??push ? %esp

?804836a: 52 ? ? ? ? ? ? ? ? ??push ? %edx

?804836b: 68 40 84 04 08 ? ? ??push ? $0x8048440

?8048370: 68 50 84 04 08 ? ? ??push ? $0x8048450

?8048375: 51 ? ? ? ? ? ? ? ? ??push ? %ecx

?8048376: 56 ? ? ? ? ? ? ? ? ??push ? %esi

?8048377: 68 14 84 04 08 ? ? ??push ? $0x8048414

?804837c: e8 ab ff ff ff ? ? ??call ? 804832c <[email protected]>

?8048381: f4 ? ? ? ? ? ? ? ? ??hlt ? ?

?8048382: 90 ? ? ? ? ? ? ? ? ??nop

?8048383: 90 ? ? ? ? ? ? ? ? ??nop

?8048384: 90 ? ? ? ? ? ? ? ? ??nop

?8048385: 90 ? ? ? ? ? ? ? ? ??nop

?8048386: 90 ? ? ? ? ? ? ? ? ??nop

?8048387: 90 ? ? ? ? ? ? ? ? ??nop

?8048388: 90 ? ? ? ? ? ? ? ? ??nop

?8048389: 90 ? ? ? ? ? ? ? ? ??nop

?804838a: 90 ? ? ? ? ? ? ? ? ??nop

?804838b: 90 ? ? ? ? ? ? ? ? ??nop

?804838c: 90 ? ? ? ? ? ? ? ? ??nop

?804838d: 90 ? ? ? ? ? ? ? ? ??nop

?804838e: 90 ? ? ? ? ? ? ? ? ??nop

?804838f: 90 ? ? ? ? ? ? ? ? ??nop

08048390 <__do_global_dtors_aux>:

?8048390: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?8048391: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?8048393: 53 ? ? ? ? ? ? ? ? ??push ? %ebx

?8048394: 83 ec 04 ? ? ? ? ? ??sub ? ?$0x4,%esp

?8048397: 80 3d 18 a0 04 08 00?cmpb ? $0x0,0x804a018

?804839e: 75 3f ? ? ? ? ? ? ? ?jne ? ?80483df <__do_global_dtors_aux+0x4f>

?80483a0: a1 1c a0 04 08 ? ? ??mov ? ?0x804a01c,%eax

?80483a5: bb 18 9f 04 08 ? ? ??mov ? ?$0x8049f18,%ebx

?80483aa: 81 eb 14 9f 04 08 ? ?sub ? ?$0x8049f14,%ebx

?80483b0: c1 fb 02 ? ? ? ? ? ??sar ? ?$0x2,%ebx

?80483b3: 83 eb 01 ? ? ? ? ? ??sub ? ?$0x1,%ebx

?80483b6: 39 d8 ? ? ? ? ? ? ? ?cmp ? ?%ebx,%eax

?80483b8: 73 1e ? ? ? ? ? ? ? ?jae ? ?80483d8 <__do_global_dtors_aux+0x48>

?80483ba: 8d b6 00 00 00 00 ? ?lea ? ?0x0(%esi),%esi

?80483c0: 83 c0 01 ? ? ? ? ? ??add ? ?$0x1,%eax

?80483c3: a3 1c a0 04 08 ? ? ??mov ? ?%eax,0x804a01c

?80483c8: ff 14 85 14 9f 04 08?call ? *0x8049f14(,%eax,4)

?80483cf: a1 1c a0 04 08 ? ? ??mov ? ?0x804a01c,%eax

?80483d4: 39 d8 ? ? ? ? ? ? ? ?cmp ? ?%ebx,%eax

?80483d6: 72 e8 ? ? ? ? ? ? ? ?jb ? ? 80483c0 <__do_global_dtors_aux+0x30>

?80483d8: c6 05 18 a0 04 08 01?movb ? $0x1,0x804a018

?80483df: 83 c4 04 ? ? ? ? ? ??add ? ?$0x4,%esp

?80483e2: 5b ? ? ? ? ? ? ? ? ??pop ? ?%ebx

?80483e3: 5d ? ? ? ? ? ? ? ? ??pop ? ?%ebp

?80483e4: c3 ? ? ? ? ? ? ? ? ??ret ? ?

?80483e5: 8d 74 26 00 ? ? ? ? ?lea ? ?0x0(%esi,%eiz,1),%esi

?80483e9: 8d bc 27 00 00 00 00?lea ? ?0x0(%edi,%eiz,1),%edi

080483f0 <frame_dummy>:

?80483f0: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?80483f1: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?80483f3: 83 ec 18 ? ? ? ? ? ??sub ? ?$0x18,%esp

?80483f6: a1 1c 9f 04 08 ? ? ??mov ? ?0x8049f1c,%eax

?80483fb: 85 c0 ? ? ? ? ? ? ? ?test ? %eax,%eax

?80483fd: 74 12 ? ? ? ? ? ? ? ?je ? ? 8048411 <frame_dummy+0x21>

?80483ff: b8 00 00 00 00 ? ? ??mov ? ?$0x0,%eax

?8048404: 85 c0 ? ? ? ? ? ? ? ?test ? %eax,%eax

?8048406: 74 09 ? ? ? ? ? ? ? ?je ? ? 8048411 <frame_dummy+0x21>

?8048408: c7 04 24 1c 9f 04 08?movl ? $0x8049f1c,(%esp)

?804840f: ff d0 ? ? ? ? ? ? ? ?call ? *%eax

?8048411: c9 ? ? ? ? ? ? ? ? ??leave ?

?8048412: c3 ? ? ? ? ? ? ? ? ??ret ? ?

?8048413: 90 ? ? ? ? ? ? ? ? ??nop

08048414 <main>:

?8048414: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?8048415: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?8048417: 83 e4 f0 ? ? ? ? ? ??and ? ?$0xfffffff0,%esp

?804841a: 83 ec 10 ? ? ? ? ? ??sub ? ?$0x10,%esp

?804841d: c7 04 24 00 85 04 08?movl ? $0x8048500,(%esp)

?8048424: e8 13 ff ff ff ? ? ??call ? 804833c <[email protected]>

?8048429: c7 04 24 00 00 00 00?movl ? $0x0,(%esp)

?8048430: e8 17 ff ff ff ? ? ??call ? 804834c <[email protected]>

?8048435: 90 ? ? ? ? ? ? ? ? ??nop

?8048436: 90 ? ? ? ? ? ? ? ? ??nop

?8048437: 90 ? ? ? ? ? ? ? ? ??nop

?8048438: 90 ? ? ? ? ? ? ? ? ??nop

?8048439: 90 ? ? ? ? ? ? ? ? ??nop

?804843a: 90 ? ? ? ? ? ? ? ? ??nop

?804843b: 90 ? ? ? ? ? ? ? ? ??nop

?804843c: 90 ? ? ? ? ? ? ? ? ??nop

?804843d: 90 ? ? ? ? ? ? ? ? ??nop

?804843e: 90 ? ? ? ? ? ? ? ? ??nop

?804843f: 90 ? ? ? ? ? ? ? ? ??nop

08048440 <__libc_csu_fini>:

?8048440: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?8048441: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?8048443: 5d ? ? ? ? ? ? ? ? ??pop ? ?%ebp

?8048444: c3 ? ? ? ? ? ? ? ? ??ret ? ?

?8048445: 8d 74 26 00 ? ? ? ? ?lea ? ?0x0(%esi,%eiz,1),%esi

?8048449: 8d bc 27 00 00 00 00?lea ? ?0x0(%edi,%eiz,1),%edi

08048450 <__libc_csu_init>:

?8048450: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?8048451: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?8048453: 57 ? ? ? ? ? ? ? ? ??push ? %edi

?8048454: 56 ? ? ? ? ? ? ? ? ??push ? %esi

?8048455: 53 ? ? ? ? ? ? ? ? ??push ? %ebx

?8048456: e8 4f 00 00 00 ? ? ??call ? 80484aa <__i686.get_pc_thunk.bx>

?804845b: 81 c3 99 1b 00 00 ? ?add ? ?$0x1b99,%ebx

?8048461: 83 ec 1c ? ? ? ? ? ??sub ? ?$0x1c,%esp

?8048464: e8 73 fe ff ff ? ? ??call ? 80482dc <_init>

?8048469: 8d bb 18 ff ff ff ? ?lea ? ?-0xe8(%ebx),%edi

?804846f: 8d 83 18 ff ff ff ? ?lea ? ?-0xe8(%ebx),%eax

?8048475: 29 c7 ? ? ? ? ? ? ? ?sub ? ?%eax,%edi

?8048477: c1 ff 02 ? ? ? ? ? ??sar ? ?$0x2,%edi

?804847a: 85 ff ? ? ? ? ? ? ? ?test ? %edi,%edi

?804847c: 74 24 ? ? ? ? ? ? ? ?je ? ? 80484a2 <__libc_csu_init+0x52>

?804847e: 31 f6 ? ? ? ? ? ? ? ?xor ? ?%esi,%esi

?8048480: 8b 45 10 ? ? ? ? ? ??mov ? ?0x10(%ebp),%eax

?8048483: 89 44 24 08 ? ? ? ? ?mov ? ?%eax,0x8(%esp)

?8048487: 8b 45 0c ? ? ? ? ? ??mov ? ?0xc(%ebp),%eax

?804848a: 89 44 24 04 ? ? ? ? ?mov ? ?%eax,0x4(%esp)

?804848e: 8b 45 08 ? ? ? ? ? ??mov ? ?0x8(%ebp),%eax

?8048491: 89 04 24 ? ? ? ? ? ??mov ? ?%eax,(%esp)

?8048494: ff 94 b3 18 ff ff ff?call ? *-0xe8(%ebx,%esi,4)

?804849b: 83 c6 01 ? ? ? ? ? ??add ? ?$0x1,%esi

?804849e: 39 fe ? ? ? ? ? ? ? ?cmp ? ?%edi,%esi

?80484a0: 72 de ? ? ? ? ? ? ? ?jb ? ? 8048480 <__libc_csu_init+0x30>

?80484a2: 83 c4 1c ? ? ? ? ? ??add ? ?$0x1c,%esp

?80484a5: 5b ? ? ? ? ? ? ? ? ??pop ? ?%ebx

?80484a6: 5e ? ? ? ? ? ? ? ? ??pop ? ?%esi

?80484a7: 5f ? ? ? ? ? ? ? ? ??pop ? ?%edi

?80484a8: 5d ? ? ? ? ? ? ? ? ??pop ? ?%ebp

?80484a9: c3 ? ? ? ? ? ? ? ? ??ret ? ?

080484aa <__i686.get_pc_thunk.bx>:

?80484aa: 8b 1c 24 ? ? ? ? ? ??mov ? ?(%esp),%ebx

?80484ad: c3 ? ? ? ? ? ? ? ? ??ret ? ?

?80484ae: 90 ? ? ? ? ? ? ? ? ??nop

?80484af: 90 ? ? ? ? ? ? ? ? ??nop

080484b0 <__do_global_ctors_aux>:

?80484b0: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?80484b1: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?80484b3: 53 ? ? ? ? ? ? ? ? ??push ? %ebx

?80484b4: 83 ec 04 ? ? ? ? ? ??sub ? ?$0x4,%esp

?80484b7: a1 0c 9f 04 08 ? ? ??mov ? ?0x8049f0c,%eax

?80484bc: 83 f8 ff ? ? ? ? ? ??cmp ? ?$0xffffffff,%eax

?80484bf: 74 13 ? ? ? ? ? ? ? ?je ? ? 80484d4 <__do_global_ctors_aux+0x24>

?80484c1: bb 0c 9f 04 08 ? ? ??mov ? ?$0x8049f0c,%ebx

?80484c6: 66 90 ? ? ? ? ? ? ? ?xchg ? %ax,%ax

?80484c8: 83 eb 04 ? ? ? ? ? ??sub ? ?$0x4,%ebx

?80484cb: ff d0 ? ? ? ? ? ? ? ?call ? *%eax

?80484cd: 8b 03 ? ? ? ? ? ? ? ?mov ? ?(%ebx),%eax

?80484cf: 83 f8 ff ? ? ? ? ? ??cmp ? ?$0xffffffff,%eax

?80484d2: 75 f4 ? ? ? ? ? ? ? ?jne ? ?80484c8 <__do_global_ctors_aux+0x18>

?80484d4: 83 c4 04 ? ? ? ? ? ??add ? ?$0x4,%esp

?80484d7: 5b ? ? ? ? ? ? ? ? ??pop ? ?%ebx

?80484d8: 5d ? ? ? ? ? ? ? ? ??pop ? ?%ebp

?80484d9: c3 ? ? ? ? ? ? ? ? ??ret ? ?

?80484da: 90 ? ? ? ? ? ? ? ? ??nop

?80484db: 90 ? ? ? ? ? ? ? ? ??nop

Disassembly of section .fini:

080484dc <_fini>:

?80484dc: 55 ? ? ? ? ? ? ? ? ??push ? %ebp

?80484dd: 89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?80484df: 53 ? ? ? ? ? ? ? ? ??push ? %ebx

?80484e0: 83 ec 04 ? ? ? ? ? ??sub ? ?$0x4,%esp

?80484e3: e8 00 00 00 00 ? ? ??call ? 80484e8 <_fini+0xc>

?80484e8: 5b ? ? ? ? ? ? ? ? ??pop ? ?%ebx

?80484e9: 81 c3 0c 1b 00 00 ? ?add ? ?$0x1b0c,%ebx

?80484ef: e8 9c fe ff ff ? ? ??call ? 8048390 <__do_global_dtors_aux>

?80484f4: 59 ? ? ? ? ? ? ? ? ??pop ? ?%ecx

?80484f5: 5b ? ? ? ? ? ? ? ? ??pop ? ?%ebx

?80484f6: c9 ? ? ? ? ? ? ? ? ??leave ?

?80484f7: c3 ? ? ? ? ? ? ? ? ??ret?

[email protected]:~/private/mytest$ gcc -c ?hello.c

hello.c: In function ‘main’:

hello.c:4: warning: incompatible implicit declaration of built-in function ‘exit’

[email protected]:~/private/mytest$ objdump -d hello.o

hello.o: ? ? file format elf32-i386

Disassembly of section .text:

00000000 <main>:

?? 0:55 ? ? ? ? ? ? ? ? ??push ? %ebp

?? 1:89 e5 ? ? ? ? ? ? ? ?mov ? ?%esp,%ebp

?? 3:83 e4 f0 ? ? ? ? ? ??and ? ?$0xfffffff0,%esp

?? 6:83 ec 10 ? ? ? ? ? ??sub ? ?$0x10,%esp

?? 9:c7 04 24 00 00 00 00?movl ? $0x0,(%esp)

??10:e8 fc ff ff ff ? ? ??call ? 11 <main+0x11>

??15:c7 04 24 00 00 00 00?movl ? $0x0,(%esp)

??1c:e8 fc ff ff ff ? ? ??call ? 1d <main+0x1d>

[email protected]:~/private/mytest$?

char*与char[]-从编译后的汇编代码分析
节 含义
.text 已编译程序的机器代码
.rodata 只读数据,如pintf和switch语句中的字符串和常量值
.data 已初始化的全局变量
.bss 未初始化的全局变量
.symtab 符号表,存放在程序中被定义和引用的函数和全局变量的信息
.rel.text 当链接器吧这个目标文件和其他文件结合时,.text节中的信息需修改
.rel.data 被模块定义和引用的任何全局变量的信息
.debug 一个调试符号表。
.line 原始C程序的行号和.text节中机器指令之间的映射
.strtab 一个字符串表,其内容包含.systab和.debug节中的符号表

1、汇编相关段 的说明在上。

2、C源代码,x为char *,y为char []

#include <stdio.h>

void main(){

?? char *x="xxxx";

?? char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097

?? printf("%s-----%s",x,y);

?? exit(0);

}

[email protected]:~/private/mytest$ gcc -S testcr.c

.file "testcr.c"

.section .rodata

.LC0:

.string "xxxx"#使用char *分配

.LC1:

.string "%s-----%s"

.text

.globl main

.type main, @function

main:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

subl$32, %esp#分配32字节栈空间,根据变量情况分配

movl$.LC0, 24(%esp)#x变量使用指针(4个字节大小),放入栈中,可以看到,变量分配靠近栈空间的尾部

movw$31097, 29(%esp)#字符‘yy‘移到main程序的栈中,直接将y变量的值放入栈中

movb$0, 31(%esp)#加上NULL标志,表示字符结束?

movl $.LC1, %eax

leal 29(%esp), %edx

movl %edx, 8(%esp)

movl 24(%esp), %edx

movl %edx, 4(%esp)

movl %eax, (%esp)

call printf

movl $0, (%esp)

call exit

.size main, .-main

.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

.section .note.GNU-stack,"",@progbits

3、由以上分析可以看出,在MAIN函数中char *分配在只读数据段中,实际使用时,只在程序栈中分配一个指针的空间。char[] 在程序栈中分配空间,然后直接使用movl、movw之类的汇编直接把值放入栈中空间。那么在其它函数中声明的呢,可以从以下程序中看出,仍然如此。


#include <stdio.h>

void myprinf(){

?? char *x="xxxx";

?? char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097

?? printf("%s-----%s",x,y);

}

void main(){

?? int num=1;

?? myprint();

?? exit(0);

}

[email protected]:~/private/mytest$ gcc -S testcr.c

ASM代码:


.file "testcr.c"

.section .rodata

.LC0:

.string"xxxx"

.LC1:

.string "%s-----%s"

.text

.globl myprinf

.type myprinf, @function

myprinf:

pushl %ebp

movl %esp, %ebp

subl $40, %esp

movl$.LC0, -16(%ebp)

movw$31097, -11(%ebp)

movb$0, -9(%ebp)

movl $.LC1, %eax

leal -11(%ebp), %edx

movl %edx, 8(%esp)

movl -16(%ebp), %edx

movl %edx, 4(%esp)

movl %eax, (%esp)

call printf

leave

ret

.size myprinf, .-myprinf

.globl main

.type main, @function

main:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

subl $32, %esp

movl $1, 28(%esp)

call myprint

movl $0, (%esp)

call exit

.size main, .-main

.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

.section .note.GNU-stack,"",@progbits

以上是关于C指针原理(20)-C指针基础的主要内容,如果未能解决你的问题,请参考以下文章

C指针原理(17)-C指针基础

C指针原理(24)-C指针基础

C指针原理(14)-C指针基础

C指针原理(15)-C指针基础

C指针原理(18)-C指针基础

C指针原理(13)-C指针基础