C language: Two examples based on function pointers analysis of _c language

Source: Internet
Author: User
Tags strcmp

The first one:
------------------------------------------------------

Copy Code code as follows:

#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)/* <-----I don't understand here.
printf ("Address of strcmp ():%p\n", f);
Else
printf ("Function Address:%p\n", f);
}

--------------------------------------------------------------
One thing I don't understand is that this program is supposed to say that F is a pointer to a function, and that the decision is to determine whether F points to the function strcmp, and if so, to output the address of the strcmp function. If not, output the address of the main function
Because the function name can be used as a pointer, the IF (f = = strcmp) should say that the address of the 2 pointers is the same, right?
I use the GDB breakpoint to this, print F and printfstrcmp get a different address ah, and can find the contents of F and *f incredibly the same, strcmp and *strcmp Same, what is the reason, how to explain?

(GDB) Print F
$ = (int (*) (const char *, const char *)) 0x8048310 <strcmp@plt>
(gdb) Print strcmp
$ = {<text variable, no debug info> 0XB7E59D20 <strcmp>
(GDB) n
printf ("Address of strcmp ():%p\n", f);
(gdb) Print strcmp
$ = {<text variable, no debug info> 0XB7E59D20 <strcmp>
(gdb) Print *strcmp
$ = {<text variable, no debug info> 0XB7E59D20 <strcmp>
(gdb) Print *f
$ = {int (const char *, const char *)} 0x8048310 <strcmp@plt>
(GDB) n
Address of strcmp (): 0x8048310
19}
(GDB) n
Later I found that the PLT refers to the process link table, is not that only in the implementation of the F = = strcmp time, the address of F and strcmp point to the same location?

later, others have found by disassembly:
==============================================
The following red lines, main and strcmp are constants (you will also find No. data segment), in which he writes the two constants to the function stack, then calls the function, makes a comparison, and then outputs. And what you call F, the function argument, is actually just a predefined reference (you can't find F in the assembly code).
-------------------------------------------------------------------------------------
. 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 $,%esp
Movl $strcmp, (%ESP)
Call Tell_me
MOVL $main,%eax
Movl%eax, (%ESP)
Call Tell_me
MOVL $,%eax
Addl $,%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,%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//disassembly of the first question
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//It should be said that when the function passes, F and strcmp address are the same
004010A6 Rep stos dword ptr [edi]
13:printf ("%0x\t%0x\n", f,strcmp); Look here, the output F is the same as the strcmp address.
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)/* <-----I don't understand here.//comparison, the output address is the same,
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=======================================================

The second one:
--------------------------------------------------------------------------------------------

Copy Code code as follows:

#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)); /*<-----The problem is here * *
return 0;
}

---------------------------------------------------------------------------------------------
Output I think should be the first output P1, p2 later to perform strcat. But the actual output situation:
Abcpacific Sea Pacific Sea abcpacific Sea
Can be found strcat before P1 execution, changed the content of the P1, what is this internal order? is printf not sequentially executed?
=======================================================

the solution obtained:
different compiler printf function parameters are in different order, strcat in printf function can look at disassembly code.
6:printf ("%s\t%s\t%s\n", p1, P2, strcat (P1, p2)); /*<-----The problem is here * *
00401045 mov edx,dword ptr [ebp-18h]
00401048 push edx
00401049 Lea EAX,[EBP-14H]
0040104C push EAX
0040104D call strcat (00401130)//You can see that the STRCAT function is called First,
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)//final invoke printf function output
00401068 Add esp,10h
===============================================
The assembly is intuitive and simple to illustrate some of the questions ....
Besides, how does GCC generate the assembly code:
1:gcc-s MAIN.C can generate
2:gcc-c main.c Generation MAIN.O
Objdump-s-D main.o > Main.asm
I prefer the second kind.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.