1. 程式人生 > >C指針原理(20)-C指針基礎

C指針原理(20)-C指針基礎

top details rod total 原理 linux中 nco start 系統

結構與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!\n");
       exit(1);
    }
    printf("message %d queue created!\n",queue_id);
    //創建發送消息結構
    printf("message send....\n");
    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\n");
       exit(1);
    }
    free(msg);//發送完畢,釋放內存
    printf("message sended!\n");

    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!\n");
       exit(1);
    }

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

    return 0;
}

效果

deepfuture@deepfuture-laptop:~/private/mytest$ ./testmessnd

message 0 queue created!

message send....

message sended!

deepfuture@deepfuture-laptop:~/private/mytest$ ./testmesrecv

message recv....

recv:deepfuture.iteye.com

deepfuture@deepfuture-laptop:~/private/mytest$?

7、字符串常量?

#include?<stdio.h>

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

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

}

dp@dp:~/test1?%?cc?test3.c?-o?mytest

dp@dp:~/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;

}

~

dp@dp:~/test1?%?cc?test1.c?-o?mytest

dp@dp:~/test1?%?./mytest

48

8、命令行參數

打印參數個數,註意,命令本身也是一個參數,所以argc至少為1。


#include?<stdio.h>

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

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

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

}

~

dp@dp:~/test1?%?cc?test2.c?-o?mytest

dp@dp:~/test1?%?./mytest?12

下面沒有使用argc參數,直接使用了argv參數,通過判斷是否null,來決定參數列表是否結束

#include?<stdio.h>

#include?<stdlib.h>

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

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

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

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

}

~

dp@dp:~/test1?%?cc?test2.c?-o?mytest

dp@dp:~/test1?%?./mytest?-a

-a

dp@dp:~/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\n",oper);

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

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

????????{

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

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

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

????????}

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

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

}

dp@dp:~/test1?%?cc?test2.c?-o?mytest

dp@dp:~/test1?%?./mytest?0?1?13?52


0

1??13??52

66

dp@dp:~/test1?%?./mytest?1?1?13?52

1

1??13??52

-66

dp@dp:~/test1?%

1、將C文件生成中間匯編

deepfuture@deepfuture-laptop:~/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調試

deepfuture@deepfuture-laptop:~/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’

deepfuture@deepfuture-laptop:~/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\n");

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\n");

(gdb) c

Continuing.

hello,world

Program exited normally.

(gdb) quit

3、gprof圖表簡檔,可進行程序相關性能統計,可統計出每個函數的調用時間 和處理器時間

deepfuture@deepfuture-laptop:~/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’

deepfuture@deepfuture-laptop:~/private/mytest$ ./hello

hello,world

deepfuture@deepfuture-laptop:~/private/mytest$ gprof hello>myhello.txt

deepfuture@deepfuture-laptop:~/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

deepfuture@deepfuture-laptop:~/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 <__gmon_start__@plt>

?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 <__gmon_start__@plt-0x10>:

?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 <__gmon_start__@plt>:

?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 <__libc_start_main@plt>:

?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 <puts@plt>:

?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 <exit@plt>:

?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 <__libc_start_main@plt>

?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 <puts@plt>

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

?8048430: e8 17 ff ff ff ? ? ??call ? 804834c <exit@plt>

?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?

deepfuture@deepfuture-laptop:~/private/mytest$ gcc -c ?hello.c

hello.c: In function ‘main’:

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

deepfuture@deepfuture-laptop:~/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>

deepfuture@deepfuture-laptop:~/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);

}

deepfuture@deepfuture-laptop:~/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);

}

deepfuture@deepfuture-laptop:~/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指針基礎