由这段代码发现的printf参数的入栈顺序

来源:互联网 发布:下载一亩田软件 编辑:程序博客网 时间:2024/04/30 13:59
#include <process.h>
#include <stdio.h>

int a[5];

void Thread( void * pParam)
{
 int i, num = 0;
  while (1)
  {
   for (i = 0;i < 5; i++)
   {
    a[i] =num;
   }
   num ++;
  }
}

int main()
{
 _beginthread(Thread,0,NULL);

 int i = 0;
 while (i < 10)
 {
  printf("%d %d %d %d %d\n",
   a[0],a[0],a[0],a[0],a[0]);
  i++;
 }

 return 0;
}

今天开始学习多线程同步的时候写了这么一段小程序,要说明由于没有进行主线程和创建的从线程的同步,所以打印不出想要的输出,之后我全输出同一个元素,输出不同值可以理解,但是输出值的时候是大值在前,开始很困惑,后来才发现时printf参数压栈时候的顺序问题。是从右向左入栈的。

你可以看看汇编的代码
11: int a = 5;
00401078 mov dword ptr [ebp-4],5
12: int b = 6;
0040107F mov dword ptr [ebp-8],6
13: printf("%d &d",a,b);
00401086 mov eax,dword ptr [ebp-8]
00401089 push eax
0040108A mov ecx,dword ptr [ebp-4]
0040108D push ecx
0040108E push offset string "%d &d" (0043101c)
00401093 call printf (00408190)
00401098 add esp,0Ch
推测应该是这样的:printf函数是先根据所有的参数生成一个字符串,再将该字符串输出的屏幕上,
因此不存在先处理哪个,先输出哪个的问题

之后又试了下普通函数

 int i = 0,j = 1;
004113FE  mov         dword ptr [i],0
00411405  mov         dword ptr [j],1
 func(i,j);
0041140C  mov         eax,dword ptr [j]
0041140F  push        eax 
00411410  mov         ecx,dword ptr [i]
00411413  push        ecx 
00411414  call        func (411028h)
00411419  add         esp,8

发现也是从右向左入栈的,后来在网上发现c语言都是从右向左入栈的,所以这个可以解释清楚了。

原创粉丝点击