On the related problems of C language function call parameter stack _c language

Source: Internet
Author: User

Order of parameters into stack

In the interview before being asked such a question, the function call, the order of the parameters into the stack from left to right, or from right to left. The order of the parameters in the stack is mainly in the invocation mode, in general, __cdecl and __stdcall are parameters from right to left into the stack.

Look at the following code:

#include <stdio.h>

int Test (int a, int b)
{
  printf ("Address of a%x.\n", &a);
  printf ("Address of B%x.\n", &b);
  return 0;
}

int main ()
{
  Test (1, 2);
  return 0;
}

The results of the 64-bit Ubuntu system run:

Address of a 1ec62c. 
Address of B 1ec628.

The result of 32-bit Ubuntu is:

Address of a bfd03290. 
Address of B bfd03294.

It can be seen that, first of all, different architectures, stack growth direction is different, some from the low address to the high address direction of growth, some from the high address to the low address direction.

You can use the following code to determine the growth direction of the stack:

typedef enum {
  Low_to_high,
  high_to_low,
  left_to_right,
  right_to_left,
}stack_direc_t;

int Stack_grow_direc ()
{
  static char *p = NULL;
  char c;

  if (p = = NULL) {
    p = &c;
    Stack_grow_direc ();
  }
  else {
    printf ("%x.\n", p);
    printf ("Second in Stack",%x.\n, &c);
    if (&c > P) {
      printf ("Stack grows from low address to high address!\n");
      return low_to_high;
    }
    else {
      printf ("Stack grows from high address to Low address!\n");
      return high_to_low;
    }
  }

What's in the stack when a function is called

Take parameters from left to right into the stack as an example:

Push arg0--high address
push arg1 ...
Push argn push
EIP
push EBP--low address

When the 32-bit system and the 64-bit system function call, do the parameters stack differently?

The problem was not long ago, when silly, I have only been concerned about the 32-bit system parameters into the stack, always thought that 64-bit system is the same, no different, now summed up two points:

64-bit system first put the incoming parameters in the register, in the function of the specific implementation of the Register value into the stack, and then go to the stack to take parameters

The order of the parameters in the 64-bit system stack is left to right (because the register passes the value first)

Look at the disassembly below:


C code same as above Ubuntu 32-bit disassembly: int main () {804846d:55 push%ebp 804846e:89 e5 mov%esp,%ebp 804847
 0:83 e4 F0 and $0xfffffff0,%esp 8048473:83 EC Sub $0x10,%esp test (1, 2); 8048476:c7 movl $0x2,0x4 (%ESP) 804847d:00 804847e:c7, Movl $0x1, (%ESP) 80)
 48485:E8 8a FF FF 8048414 <test> return 0;           804848A:B8 mov $0x0,%eax} int Test (int a, int b) {8048414:55 push%ebp 8048415:89 e5
 MOV%esp,%ebp 8048417:83 EC Sub $0x18,%esp printf ("Address of a%x.\n", &a);       804841A:B8 mov $0x8048560,%eax 804841f:8d 0x8 (%EBP),%edx 8,048,422:89 54 24 04 mov%edx,0x4 (%esp) 8048426:89 mov%eax, (%ESP) 8048429:E8-FF FF FF call 8048340 <printf
 @plt > return 0;     8048466:B8 mov $0x0,%eax} Ubuntu 64-bit disassembly: int main () {40056e:55      Push%rbp 40056f:48 e5 mov%rsp,%rbp test (1, 2); 400572:BE mov $0x2,%esi 400577:BF mov $0x1,%edi 40057c:e8 ac FF FF FF CALLQ
 40052d <test> return 0;         400581:B8 mov $0x0,%eax} int Test (int a, int b) {40052d:55 push%rbp 40052e:48 m e5   MOV%RSP,%RBP 400531:48-EC sub $0X10,%RSP 400535:89 7d FC mov%edi,-0x4 (%RBP) 400538:
 F8 mov%esi,-0x8 (%RBP) printf ("Address of a%x.\n", &a);  40053b:48 8d FC Lea-0x4 (%RBP),%rax 40053f:48, C6 mov%rax,%rsi 400542:bf mb

  $0x400614,%edi 400547:B8 mov $0x0,%eax 40054c:e8 BF fe FF FF CALLQ 400410 <printf@plt>
 return 0; 400567:B8 mov $0x0,%eax}

Look at the 32-bit Ubuntu operating system, 8048476: It is really the parameters directly into the stack, 2 first into the stack, 1 back into the stack.

 8048476:  C7  movl  $0x2,0x4 (%ESP)
 804847d: 
 804847e:  C7 ' a 00
   MOVL  $0x1, (%ESP)
 8048485:  E8 8a FF FF FF     call  8048414 <test>

Looking at the 64-bit Ubuntu operating system, 2 and 1 were not put into the stack at all, but were placed in registers ESI and EDI.

 40056f:  e5        mov  %rsp,%rbp
 Test (1, 2);
 400572:  $0x2,%esi
 400577: "  bf"     mov  $0x1,%edi
 40057c:  E8 AC FF FF FF     CALLQ 40052d <test>

Then look at the 64-bit system test implementation, the first EDI into the stack, and then the ESI into the stack, which is why the function looks like a left to right into the stack reason.

40052d:           push  %rbp
40052e:  e5        mov  %rsp,%rbp
400531: MB  EC Ten       Sub  $0x10,%rsp
400535:  7d FC        mov  %edi,-0x4 (%RBP)
400538:  F8        mov  %esi,-0x8 (%RBP)

The above is a small series for everyone to talk about the C language function to call the parameters of the stack of all the contents of the relevant issues, I hope to help you, a lot of support cloud Habitat Community ~

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.