由于函数的调用约定说明哪些寄存器被保留,寄存器可以用作循环计数器吗?我可以使用寄存器作为循环计数器吗?
我首先想到的是,ecx
寄存器用作循环计数器,但查不到,我已经使用了stdcall
功能尚未保存的ecx
值后,我以为不然。
是否有保存的寄存器(通过至少大多数使用的调用约定)被保留?
注意:我没有在使用堆栈变量作为循环计数器的问题,我只是想确保它是唯一的方法。
由于函数的调用约定说明哪些寄存器被保留,寄存器可以用作循环计数器吗?我可以使用寄存器作为循环计数器吗?
我首先想到的是,ecx
寄存器用作循环计数器,但查不到,我已经使用了stdcall
功能尚未保存的ecx
值后,我以为不然。
是否有保存的寄存器(通过至少大多数使用的调用约定)被保留?
注意:我没有在使用堆栈变量作为循环计数器的问题,我只是想确保它是唯一的方法。
你可以使用任何通用寄存器,偶尔也可以使用其他的作为循环计数器(当然不是栈指针)。
要么你手动使用一个循环,即替换...
loop label
...与...
dec ebp
jnz label
...这是更快呢(因为AMD(以及后来的英特尔,当他们追了上来,以MHz为单位)人为地减慢了指令的速度,否则Windows®和一些Turbo Pascal编译软件崩溃)。
,或者你只是保存在柜台之间:
label:
push ecx
call func
pop ecx
loop label
两者都是标准的战略。
是否有保存的寄存器(通过至少大多数使用的调用约定)被保存?
如果您的循环代码不会调用任何外部实体,您可以在自己的代码中选择任何免费注册表。
如果您的循环代码将调用一个外部实体,其中唯一有保证的合约是ABI并且调用约定,那么您必须保存/恢复您的寄存器,并根据具体情况制定寄存器选择。
引用昂纳雾的优秀论文Calling conventions for different C++ compilers and operating systems:
6寄存器用法
对寄存器的使用的规则依赖于操作系统,如表4所示。暂存寄存器是寄存器,可以是用于没有限制的临时存储(也称为呼叫者保存或易失性寄存器)。被调用保存寄存器是在使用它们之前必须保存的寄存器,并在使用它们(也称为非易失性寄存器)后进行恢复。你可以依靠具有呼叫作为呼叫之前之后的值相同,这些寄存器...
...
参见:
你可以推'ecx'堆栈上和它之前,你'ret'恢复,或者你可以只使用另一个寄存器 –
'推ECX '在调用返回之后,每次通过循环时使'stdcall'和'pop ecx'之前。 – lurker