2012-03-07 9 views
11

私は、Cコードから呼び出し可能でなければならないx86アセンブリの関数を書いています。呼び出し元に戻る前に復元する必要があるレジスタが不思議です。 現在、私はespとebpを復元していますが、戻り値はeaxです。 私が心配しなければならない他のレジスタはありますか?cでx86関数呼び出し後に復元されるレジスタは何ですか?

+1

一般的な規則はありません。期待していることを確認するには、Cコンパイラのドキュメントを参照する必要があります。 –

+0

私はJerryが正しいと確信しています。それは呼び出し規約に依存します。メモリが使えば、Windows、Posixなどでは「標準」の規約が異なります。どのコンパイラを使用していますか? –

+0

gcc。私はこの検索http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions(終了シーケンスを参照してください)が見つかりましたが、レジスタについては何も言わず、呼び出し元が予期していた状態に復元する必要があります。 – bobbaluba

答えて

9

Microsoft's 32 bit ABI,EAX,EDXおよびECXをスクラッチレジスタとすると、その他はすべて保存する必要があります。 Windowsでx64の

Microsoft saysあなただけRBXRBPRDIRSIR12R13R14、およびR15を復元する必要があります。

System V & AMD64 (see figure 3.4)次のものの下にx64の場合

、そのRBPRBXRSPR12R13R14、およびR15(カーネルは、レジスタの1セットを使用し、ユーザランドのコードは、別のセットを使用しているため、彼らはこれがでて設定されている、奇妙に見えますABIドキュメンテーションの付録A)。

6
32-bit: EBX, ESI, EDI, EBP 
64-bit Windows: RBX, RSI, RDI, RBP, R12-R15, XMM6-XMM15 
64-bit Linux,BSD,Mac: RBX, RBP, R12-R15 

詳しくは、Agner Fogの「Software optimization resources」を参照してください。呼び出し規約については、this pdfに記載されています。

+0

RSP =) –

+0

@StephenCanonとEIP/RIP :) –

+0

忘れずに、私もそれを指摘するつもりでしたが、 'ret'命令があなたのために命令ポインタを処理します。 –

1

レジスタの状況が不明な場合は、以下の手順で簡単にその日を節約できます。

PUSHA/PUSHAD -- Push all General Registers
POPA/POPAD -- Pop all General Registers

これらの命令は、プッシュおよび特定のために、汎用およびSI/ESI、DI/EDIレジスタをポップ。

PUSHA/PUSHAD命令の順序は次のとおりです。

Opcode Instruction Clocks Description 

60  PUSHA  18  Push AX, CX, DX, BX, original SP, BP, SI, and DI 
60  PUSHAD  18  Push EAX, ECX, EDX, EBX, original ESP, EBP ESI, and EDI 

POPA/POPAD命令の順序は次のとおりです。

Opcode Instruction Clocks Description 

61  POPA   24  Pop DI, SI, BP, SP, BX, DX, CX, and AX 
61  POPAD   24  Pop EDI, ESI, EBP, ESP(***),EBX, EDX, ECX, and EAX 

(逆の順序で)*** ESP値が破棄される代わりのESPにロードされます。

+1

'POPA'と' POPAD'命令は実際に(E)SPレジスタをポップしません!また、 'POPAD'のエラーを修正してください。あなたはEBXレジスタを忘れてしまいました。さらに、あなたは間違ってこれらの命令が*セグメントレジスタ*に触れていると言っています! –

関連する問題