汇编:主程序调用子程序,哪位高手来保存寄存器的值到栈中

汇编:主程序调用子程序,谁来保存寄存器的值到栈中?
王爽老师那本书上面好像说过:主程序将控制交给子程序的时候,
子程序应该先将自己要用到的寄存器的原值保存起来,然后再使用,使用完之后再复原,并将控制交换给主程序。
那么问题来了,
我在看professional assembly language的时候,
call printf
执行之前和执行之后,%ecx寄存器的值为何不一样了?
作者是在调用前将%ecx保存在栈中的,不是应该printf函数里面做这件事情么。怎么主程序做了。。。。
求大神解答。

------解决思路----------------------
如果在子程序里保存寄存器的值,那么调用前后不需要push和pop,主程序的代码较简捷,不容易出错,就是健壮性较好。
如果在主程序调用子程序前保存寄存器,那么每调用一次都要push和pop,代码量增加;但是如果主程序里用不到那个寄存器就可以不用保存,这时程序效率会略高一点。
我发现一般像操作字符串,除法之类需要计次循环的都会改变ecx的值,就是他们自己都不会保存ecx寄存器。如果自己写子程序还是在子程序里保存寄存器的值吧,不容易出错。
------解决思路----------------------
这个涉及到寄存器使用的个约定吧,有三个寄存器 eax、edx、ecx 是子程/函数可以随意使用而不用进行保存恢复的,而且 eax 更是作为函数的结果返回。其它的寄存器,如果子程/函数使用了,则必须进行保存恢复的操作。
------解决思路----------------------
LZ需要这个:X86调用约定