国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 編程 > C > 正文

c語言:基于函數指針的兩個示例分析

2020-01-26 16:14:12
字體:
來源:轉載
供稿:網友

第一個:
------------------------------------------------------

復制代碼 代碼如下:

#include <stdio.h>
#include <string.h>
void tell_me(int f(const char *, const char *));
int main(void)
{
   tell_me(strcmp);
   tell_me(main);
   return 0;
}
void tell_me(int f(const char *, const char *))
{
   if (f == strcmp) /* <-----我不理解這里*/
      printf("Address of strcmp(): %p/n", f);
   else
      printf("Function address: %p/n", f);
}

--------------------------------------------------------------
其中我不理解的是,這個程序表達的應該是說f是一個指向函數的指針,判斷的時候是判斷f是否指向函數strcmp,如果是的話,就輸出strcmp這個函數的地址.如果不是,就輸出main函數的地址
因為函數名可以作為指針,所以if (f == strcmp)應該是說判斷2個指針的地址是否相同對吧?
我用gdb 斷點到此,print f和printfstrcmp得到的是不同的地址啊,并且可以發現f和*f的內容居然一樣,strcmp和*strcmp也一樣,請問是什么原因,如何解釋?

(gdb) print f
$1 = (int (*)(const char *, const char *)) 0x8048310 <strcmp@plt>
(gdb) print strcmp
$2 = {<text variable, no debug info>} 0xb7e59d20 <strcmp>
(gdb) n
16 printf("Address of strcmp(): %p/n", f);
(gdb) print strcmp
$3 = {<text variable, no debug info>} 0xb7e59d20 <strcmp>
(gdb) print *strcmp
$4 = {<text variable, no debug info>} 0xb7e59d20 <strcmp>
(gdb) print *f
$5 = {int (const char *, const char *)} 0x8048310 <strcmp@plt>
(gdb) n
Address of strcmp(): 0x8048310
19 }
(gdb) n
后來我查到plt是指的過程鏈接表,是不是說只有在執行到f == strcmp時候,才把f的地址和strcmp的位置指向同一位置?

后來別人通過反匯編發現的情況:
==============================================
如下紅色的幾行,main與strcmp此時為常量(你也會發現沒有.data段),在匯編代碼中他是把這兩個常量寫入函數堆棧,然后調用函數,作出對比,然后輸出。而你所說的 f ,也就是函數參數,實際上它只作為預分配的參考(匯編代碼中,你是找不到 f 的)。
-------------------------------------------------------------------------------------
.file "1.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
movl $strcmp, (%esp)
call tell_me
movl $main, %eax
movl %eax, (%esp)
call tell_me
movl $0, %eax
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.section .rodata
.LC0:
.string "Address of strcmp(): %p/n"
.LC1:
.string "Function address: %p/n"
.text
.globl tell_me
.type tell_me, @function
tell_me:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
cmpl $strcmp, 8(%ebp)
jne .L4
movl 8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
jmp .L6
.L4:
movl 8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC1, (%esp)
call printf
.L6:
leave
ret
.size tell_me, .-tell_me
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
==================================================
00401090 push ebp //第一題的反匯編
00401091 mov ebp,esp
00401093 sub esp,40h
00401096 push ebx
00401097 push esi
00401098 push edi
00401099 lea edi,[ebp-40h]
0040109C mov ecx,10h
004010A1 mov eax,0CCCCCCCCh //應該說在函數傳遞時,f與strcmp的地址都相同
004010A6 rep stos dword ptr [edi]
13: printf("%0x/t%0x/n",f,strcmp); //看這里,輸出f與strcmp的地址是相同的
004010A8 push offset strcmp (004011a0)
004010AD mov eax,dword ptr [ebp+8]
004010B0 push eax
004010B1 push offset string "%0x/t%0x/n" (0042201c)
004010B6 call printf (00401120)
004010BB add esp,0Ch
14: if (f == strcmp) /* <-----我不理解這里*/ //比較后,輸出的地址同樣是一樣的,
004010BE cmp dword ptr [ebp+8],offset strcmp (004011a0)
004010C5 jne tell_me+4Ah (004010da)
15: printf("Address of strcmp(): %0x/n", f);
004010C7 mov ecx,dword ptr [ebp+8]
004010CA push ecx
004010CB push offset string "Address of strcmp(): %0x/n" (00422044)
004010D0 call printf (00401120)
004010D5 add esp,8
16: else
004010D8 jmp tell_me+5Bh (004010eb)
17: printf("Function address: %p/n", f);
004010DA mov edx,dword ptr [ebp+8]
004010DD push edx
004010DE push offset string "Function address: %p/n" (00422028)
004010E3 call printf (00401120)
004010E8 add esp,8=======================================================

第二個:
--------------------------------------------------------------------------------------------

復制代碼 代碼如下:

#include <stdio.h>
#include <string.h>
int main(void)
{
   char p1[20] = "abc", *p2 = "pacific sea";
   printf("%s %s %s/n", p1, p2, strcat(p1, p2)); /*<-----問題出在這里*/
   return 0;
}

---------------------------------------------------------------------------------------------
輸出我的認為應該是先輸出p1, p2以后再執行strcat. 但是實際輸出的情況:
abcpacific sea pacific sea abcpacific sea
可以發現strcat先于p1執行,改變了p1的內容,請問這個內部是怎么的順序?難道printf不是順序執行的?
=======================================================

得到的解答:
不同的編譯器printf的函數參數進棧順序不同,printf函數中的strcat可以看反匯編代碼.
6: printf("%s/t%s/t%s/n", p1, p2, strcat(p1, p2)); /*<-----問題出在這里*/
00401045 mov edx,dword ptr [ebp-18h]
00401048 push edx
00401049 lea eax,[ebp-14h]
0040104C push eax
0040104D call strcat (00401130) //可以看到是先調用strcat函數的,
00401052 add esp,8
00401055 push eax
00401056 mov ecx,dword ptr [ebp-18h]
00401059 push ecx
0040105A lea edx,[ebp-14h]
0040105D push edx
0040105E push offset string "%s/t%s/t%s/n" (0042201c)
00401063 call printf (004010a0) //最后調用printf函數輸出
00401068 add esp,10h
===============================================
匯編直觀而簡單的說明了一些疑問....
再說下gcc如何產生匯編代碼:
1: gcc -S main.c 可以生成
2: gcc -c main.c 生成main.o
objdump -S -D main.o > main.asm
我更傾向于第二種.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
国产午夜电影| 国产盗摄一区二区| 国产超碰在线| 国产成人综合亚洲欧美在| 国产精品自产拍在线观看2019| 免费观看一二区视频网站| 免费精品国产自产拍在| 国产永久在线观看| 国产精品久久人| av文字幕在线观看| 超碰在线国产| 国产不卡在线| 九九热免费视频| 尤物视频在线免费观看| 国产大学生粉嫩无套流白浆| wwww在线观看| 国产福利微拍精品一区二区| av手机免费在线观看| 欧美日韩一区二区三区视视频| 国产美女av| 在线观看免费高清完整| 国产免费高清| 国产精品视频二区三区| 在线免费看黄网站| 免费观看久久久久| 在线午夜影院| 国产中文字幕在线观看| 在线播放一区二区精品产| 久热中文字幕在线观看| 在线免费看黄网站| 国产一二三在线观看| 国产区在线看| 午夜国产福利在线| 粉嫩av一区| 日本福利午夜视频在线| 99久热re在线精彩视频| 国产野外战在线播放| 国产免费麻豆视频| 国产美女免费观看| 国产免费视频| 日韩av成人| 人成在线免费视频| 天天干天天摸| 精品日韩av| 国产9色视频| 国产福利在线观看| 92国产在线视频| 国产成人综合美国十次| 国产精品白浆视频免费观看| 国产三区在线观看| 国产精品理人伦一区二区三区| 丁香婷婷在线观看| 最近中文字幕av免费高清| 国产美女在线看| 国产三线在线| 在线伊人免费视频| 亚洲精品影院在线| 日本黄色免费网址| 麻豆精品视频入口| 欧美高清视频| 国产精品一卡二卡三卡| 国产免费网址| 国产成人夜间影院在线观看| 精品一区二区三区在线成人| 国产va在线| www在线免费观看视频| 国产美女视频网站| 精品欧美色视频网站在线观看| 国产高清一区二区三区视频| 国产www在线观看| 超碰在线免费播放| 国产国产国产国产国产国产| 91九色在线看| 九色自拍视频| 天堂资源中文在线| 超碰在线国产| 亚洲sss视频| 黄色一级片视频| 91涩漫在线观看c| 天堂在线免费观看| 日本h视频在线观看| 精品一区二区在线欧美| 国产在线观看a视频| 9色在线视频网站| 最新超碰在线| jizz亚洲| 亚洲欧洲成人| 精品黄色免费中文电影在线播放| 老司机精品视频一区二区| 国产小视频在线| 久久久久久久久免费视频| 在线免费国产| 国产不卡一卡2卡三卡4卡5卡在线| 黄色国产网站在线观看| av首页在线| 亚洲网站视频在线观看| 国产高清av| 91亚洲精选| 97中文字幕| 精品国产免费第一区二区| 国产欧美日韩专区| 国产一卡2卡3卡4卡网站免费| 老司机在线视频二区| 日本电影全部在线观看网站视频| 国产三级av在线| 中文字幕久热在线精品| 最新国产在线精品91尤物| 中文字幕在线永久在线视频| 国产乱子伦三级在线播放| 国产女王在线**视频 | 日p在线观看| 青青草免费在线观看| 免费在线播放av| 免费看av大片| 日本中文字幕在线看| 国产亚洲精品久久久久久青梅 | 91视频久色| av网址在线播放| 女同一区二区免费aⅴ| 黄网站app在线观看下载视频大全官网| 九九热在线播放| 国产95在线|亚洲| 久热中文字幕精品视频在线| 国产亚洲精品自在线观看| 四虎影视成人永久免费观看视频| 九九热精品在线视频| 精品乱码一区二区三四区视频| 日韩欧美中文字幕不卡| 午夜国产福利在线| 国产黄网站在线观看| 小说区乱图片区| 国产youjizz在线| 欧美日韩在线视频免费观看| 国产精品粉嫩av| 国产精品一区二区婷婷| 亚洲网站一区| 97高清视频| 国产精品久久在线| 狠狠干在线视频| 亚洲www色| 91香蕉视频免费在线观看| 国产美女自拍视频| 波多野结衣久久高清免费| 在线中文字幕av| 日本最新在线视频| 久久精品视频观看| 一本大道久久精品| ·天天天天操| 精品av中文字幕在线毛片| 国产精美视频| 国产亚洲精品久久久久久青梅| 欧美日韩在线中文字幕| 日本一卡二卡四卡精品| 亚洲欧美精品日韩欧美| 在线国产1区| 日本免费视频www| 天天操中文字幕视频| av在线免费播放网站| 亚洲字幕成人中文在线观看| 国产高清视频免费最新在线| 国产啊啊啊视频在线观看| 国产91在线视频蝌蚪| 在线成人综合色一区| sese在线视频| 国产乱在线观看视频| 国产精品美女视频免费观看软件 | 99精品老司机免费视频| 精品51国产黑色丝袜高跟鞋| 国产高清视频在线观看| 最新av中文字幕| 国产福利小视频在线| 中文在线观看视频| 欧美色第一页| 最近中文字幕在线中文视频| 国产二区在线播放| 日韩不卡高清| 成人av小说网| 精品国产免费观看一区| 另类综合图区| 精品一二三区视频| 九七电影韩国女主播在线观看| 国产视频福利| 四虎成人精品在永久在线观看| 亚洲免费网站在线观看| 激情亚洲综合网| 精品伦理一区二区| 国产精品一区在线看| 夜夜操天天干| 国产一级二级在线| 免费在线观看a| 91中文字幕网| 国产午夜在线视频| 免费观看久久久久| 99精品老司机免费视频| 国产卡1卡2卡三卡在线| 尤物在线视频观看| 国产精品jvid在线观看| 国产精品一区二三区| v天堂福利视频在线观看| 国产丝袜自拍|