由於函數的調用約定說明哪些寄存器被保留,寄存器可以用作循環計數器嗎?我可以使用寄存器作爲循環計數器嗎?
我首先想到的是,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