l******d 发帖数: 530 | 1 比如printf()这种变长参数个数的函数,调用是stack里是需要push哪些东西的,跟普通的定长
参数函数调用有何不同呢?谢谢 |
G******e 发帖数: 229 | 2 Use the varargs facility: #include |
l******d 发帖数: 530 | 3 那运行时push什么进stack呢?跟普通的定长参数函数调用有不同吗?谢谢。
【在 G******e 的大作中提到】 : Use the varargs facility: #include
|
G******e 发帖数: 229 | 4
Sorry, I know little about the implementation of this facility. It seems the
implementation is compiler-dependent, see e.g. http://gcc.gnu.org/onlinedocs/gccint/Varargs.html.
【在 l******d 的大作中提到】 : 那运行时push什么进stack呢?跟普通的定长参数函数调用有不同吗?谢谢。
|
d***p 发帖数: 128 | 5 以前刚好写过printf这个函数。“”内的参数是以字符串的形式存在,到stack的是它
的地址,当然你可以随便写内容了。之后的参数就反方向入stack。再之后PC,FP,函数
里的变量入stack。欢迎讨论 |
c******e 发帖数: 545 | 6 这种函数都是__cdecl调用,参数从右向左压栈,主调函数清栈。
format string在最左(printf)或次左(fprintf,sprintf...),所以用[BP]访问的时候
位置可预测,然后根据format string生成每个参数的偏移地址。
一般来说函数调用大致顺序(__cdecl)是:
1.主调函数从右到左压参数
2.建立栈帧
1)保存BP(32位下EBP,下同)push bp
2)保存当前栈位置:mov bp,sp
因为BP和SP默认同时用栈段(SS),用BP上可访问参数,下可访问局部变量,一般不用
SP,因为SP总是在变。
3.函数体
4.恢复bp:mov sp,bp pop bp
4.函数返回
5.主函数清栈(xxx是参数大小):add sp,xxx
时间太久可能细节不太准确,不过大致过程应该差不多,可以使用变长参数的两个决定
因素是:1. 右到左压栈 2. 主调函数清栈 |
c******e 发帖数: 545 | 7 如果有局部变量的话还要修改sp来reserve空间:
sub sp, yyy |