在这种特殊情况下,您是否建议使用程序集访问参数
would you recommend using assembly to access arguments in this exceptional case?
考虑以下不会内联的函数,并假设x86为平台:
void doSomething(int & in){
//do something
}
首先,我不确定这种情况会发生,但由于我认为这是可能的,我会问,如果在任何调用方中,无论何时调用该函数,要提供的参数都正好位于调用方堆栈帧的顶部,因此在被调用的函数中,可以用汇编语言通过ebp寄存器(在被调用方将esp的内容移动到ebp中之后)访问它,你建议我们忽略为函数声明一个参数,在这种特殊情况下使用汇编访问我们的参数,或者只保留函数定义的原样,让编译器做它该做的事情?由于我在任何地方都没有读过编译器会将这种特殊情况视为调用约定的一个因素,我认为它只会生成代码,将指向参数的指针传递给被调用方堆栈帧或寄存器
首先,它很容易被破坏——例如,你得到了一个不同版本的编译器,它以不同的方式生成代码。或者您更改优化功能。不要介意突然需要在不同的地方使用doSomething
,然后它就不起作用了,因为变量不再在堆栈的顶部。
其次,假设函数内的代码足够短,编译器很可能会内联函数,这样就不会"丢失"任何东西。
第三,在现代编译器中,一个参数通常会在寄存器中传递,因此当启用优化时,这没有任何好处。
如果你真的认为这有好处,并且编译器不会内联或以其他方式优化代码[你看过生成的代码吗?],那么试着使用forceinline
或always_inline
或编译器中调用的任何代码(大多数编译器都有这样的选项)。如果这不起作用,请使用宏手动内联。或者简单地将代码移动到"复制粘贴"所调用的位置。
您的注释"要提供的参数正好位于调用方堆栈帧的顶部,因此在被调用函数中,通过ebp register访问它"包含了一个事实误解。
这是因为以下几点:
- 您假设了一个基于堆栈的调用约定,即在
call
调用函数之前,调用方将函数参数push
添加到堆栈中。通常情况并非如此;即使在32位x86上,也有基于非堆栈的调用约定(例如,Windowsfastcall
或32位linux内核中使用的GNU GCC)。如果使用这样的方法,则不会在堆栈顶部找到参数,而是在。。。用于保存第一个参数的任何寄存器
但是,即使您有基于堆栈的参数传递。。。仍然: - 您已经忽略了,在x86上,
call
指令至少会将返回地址推送到堆栈顶部,因此当以这种方式到达的函数的第一条指令正在执行时,ESP
不会指向该函数的第一个arg,而是指向返回地址 - 您已经错过了
EBP
是一个被调用者保存(保存在函数调用中)的寄存器,而不是由体系结构代表您初始化的——生成的代码必须显式地设置它。因此,想要使用它(即使只是作为帧指针)的函数必须在使用它之前将其保存在某个位置。这意味着正常序言将具有push EBP; mov EBP, ESP
(您不能仅执行MOV EBP, ESP
,因为这将覆盖调用方的EBP
,而这是无效的/您可能不会执行的)。因此,如果要引用函数的第一个参数,则需要[ EBP + 8 ]
而不是[ EBP ]
如果不是使用帧指针,则第一个参数(由于用于到达推送返回地址的函数的call
)位于[ ESP + 4 ]
而不是[ ESP ]
我希望这能澄清一点。
我同意其他海报的观点,即澄清这个问题会有所帮助,你到底想实现什么,以及为什么你认为汇编语言在这里可能有用。
不,我不会。调用约定可能有所不同(在x86和x86_64之间);参数可以被推送到堆栈或放入寄存器,我不确定你是否能确定它们会在哪里
除非您真的知道自己在做什么,否则在程序集中编写它可能会导致未定义的行为代码。
- 内联程序集printf将整数解释为地址
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 具有外部"c"和程序集的未定义函数
- 用于将C++代码转换为 Web 程序集的脚本未终止
- 为什么我的C++程序的程序集输出充满了 .ascii,没有汇编代码?
- CoreCLR 中的检测探查器 - 将帮助程序程序集加载到 dotnet 进程的方法
- 不同于按值传递和常量引用传递的程序集
- 为什么在堆栈和堆上创建变量会产生相同的程序集代码?
- C++变量在调用 x64 程序集函数后重置为 0
- 如何访问QT中传递给程序的参数
- 如何将C++子例程链接到 x86 程序集程序?
- 如何在程序集函数中将元素数组作为参数传递时转发 ARM 寄存器的地址指针
- 混合 c++ 和汇编不能将多个参数从C++函数传递到程序集
- 参数传递和返回值如何在程序集级别的 x86 上的 C/C++ 中工作?
- 将引用参数传递给程序集函数
- 检索x64 masm程序集过程的参数
- 在 C 和内联程序集之间传递参数
- 在这种特殊情况下,您是否建议使用程序集访问参数
- x86 程序集比较参数
- 如何将数组引用作为参数从程序集传递给c++函数