如果我有一个函数foo(arg1,arg2)。在IA32堆栈中,首先推入arg2,然后推入arg1,这样被调用函数通过%ebp + 8访问arg1并通过%ebp + 12访问arg2,但是推回的原因是什么? (我们的处理器提到了一些关于printf和count的内容,但我不太明白)。另外一般来说,调用函数从不传递参数的数量(有多少个参数),那么被调用函数怎么知道呢? 非常感谢!为什么在IA32堆栈过程中向后传递参数?
1
A
回答
1
在汇编层面,如果您以书面或倒序的方式在堆栈上传递参数并不重要,但所选方法必须与被调用函数所使用的方法相同。 C通常以相反的顺序推送值,因为它需要支持varargs
- 可变数量的参数。如果按照书面顺序推送参数,那么得到第一个参数并不容易。
像Java或C#(以及.NET一般)等现代语言可以正常推送值,因为它们处理数组的附加参数(所以只有一个参数传递给被调用的函数 - 指向数组的指针)。
C的例子:
.data
format: db "Your lucky number is %d", 0
....
;code is equivalent to printf("Your lucky number is %d", 10);
push dword 10
push format
call printf
Java示例:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Your lucky number is %d
5: iconst_1
6: anewarray #4 // class java/lang/Object
9: dup
10: iconst_0
11: bipush 10
13: invokestatic #5 // Method java/lang/Integer.valueOf(I)Ljavava/lang/Integer;
16: aastore
17: invokevirtual #6 // Method java/io/PrintStream.printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
20: pop
+0
“推10”从哪里来? – user1849043
+0
这是要打印的号码。 – user35443
相关问题
- 1. 将参数通过堆栈传递给MASM中的过程
- 2. 在堆栈上传递参数
- 3. x86程序集:通过堆栈将参数传递给函数
- 4. 绕过核心数据堆栈传递
- 5. 通过堆栈传递数据
- 6. python - 通过堆栈装饰器传递函数参数
- 7. 过程递归和堆栈
- 8. 什么用户参数从MEAN堆栈中的服务器传递到前端?
- 9. 为什么要通过线程函数传递参数?
- 10. c/C++通过参考堆栈帧布局的指针/参数传递参数
- 11. 为什么堆栈中总会有无用的函数参数?
- 12. 堆栈为空...为什么?
- 13. 为什么2堆栈对于后序横向如此有效
- 14. 参数在变量参数函数中如何传递到堆栈上?
- 15. 什么在堆栈中?
- 16. 为什么在堆栈中零片段
- 17. 为什么堆栈溢出?
- 18. 为什么堆栈有界?
- 19. 为什么堆栈炸毁
- 20. 为什么递归懒惰列表在Scala中打击堆栈?
- 21. MEAN堆栈传递参数在路由器内
- 22. 不能在passport.js传递的参数 - MEAN堆栈
- 23. 在NASM堆栈上传递参数的问题
- 24. 程序集:在使用堆栈时将参数传递给函数有什么好处吗?
- 25. 为什么在通过参数传递值时会得到零?
- 26. 你为什么不传递参数?
- 27. 传递通过引用一个堆栈中分配参数的阵列
- 28. 将函数的参数传递给堆栈还是寄存器?
- 29. 数组的使用堆栈(参数传递/返回)
- 30. 线程堆栈和进程堆栈有什么区别
这只是C调用约定。 C支持具有可变数量参数的函数,main()和printf()是常见的例子。通过将它们“向后”传递,第一个参数总是在已知位置。 –
被调用者将“知道”有多少个参数,因为*编译器*在编译时知道并且看到保留适当数量的堆栈空间并生成代码来访问这些值。任何数量的var-args都会隐式转换为单个*数组*(加上数组的长度),并作为参考传递给被调用者。 – JimmyB
而在C约定中,参数的可变数总是第一个?这是有道理的。然而,如果你按照正常顺序推动它们,你也会知道“参数的数量”总是最后一个,对吧? – user1849043