करने की स्पष्ट बात यह है कि ब्याज के मशीन निर्देशों के तत्वों की पीढ़ी का प्रतिनिधित्व करने वाले अवशेषों का एक सेट तैयार किया गया है, और फिर निर्देशों/पते को प्राप्त करने के लिए कॉल लिखने के लिए कॉल लिखें। यदि आप विभिन्न प्रकार के कोड उत्पन्न करते हैं, तो आप इस तरह के पूरे निर्देश सेट को एन्कोडिंग समाप्त कर सकते हैं।
ObjectCodeEmitMovRegister32ScaledRegister32OffsetRegister32(EAX,EDX,4,-LowerBound*4,ESP);
आप बता सकते हैं मैं लंबे समय के नाम की तरह:
फिर एक MOV अनुदेश उत्पन्न करने के लिए, आप कोड ऐसा दिखता है जैसे लिख सकते हैं। (कम से कम मैं वे क्या करते हैं कभी नहीं भूल सकता।)
यहाँ इस है कि मैं एक लंबे समय पहले सी में लागू समर्थन एक कोड जनरेटर के कुछ टुकड़े है। इसमें सबसे कठिन हिस्सा शामिल है, जो एमओडी और एसआईबी बाइट्स की पीढ़ी है। इस शैली के बाद कोई भी एक पसंद के रूप में निर्देश सेट को लागू कर सकता है। यह उदाहरण केवल x32 के लिए है, इसलिए ओपी को तदनुसार विस्तार और संशोधित करना होगा। एमओवी निर्देश जनरेटर की परिभाषा अंत में नीचे है।
#define Register32T enum Register32Type
enum Register32Type {EAX=0,ECX=1,EDX=2,EBX=3,ESP=4,EBP=5,ESI=6,EDI=7};
inline
byte ObjectCodeEmitModRM32Register32(Register32T Register32,Register32T BaseRegister32)
// Send ModRM32Bytes for register-register mode to object file
{ byte ModRM32Byte=0xC0+Register32*0x8+BaseRegister32;
ObjectCodeEmitByte(ModRM32Byte);
return ModRM32Byte;
}
inline
byte ObjectCodeEmitModRM32Direct(Register32T Register32)
// Send ModRM32Bytes for direct address mode to object file
{ byte ModRM32Byte=Register32*0x8+0x05;
ObjectCodeEmitByte(ModRM32Byte);
return ModRM32Byte;
}
inline
void ObjectCodeEmitSIB(Register32T ScaledRegister32,
natural Scale,
Register32T BaseRegister32)
// send SIB byte to object file
// Note: Use ESP for ScaledRegister32 to disable scaling; only useful when using ESP for BASE.
{ if (ScaledRegister32==ESP && BaseRegister32!=ESP) CompilerFault(31);
if (Scale==1) ObjectCodeEmitByte((byte)(0x00+ScaledRegister32*0x8+BaseRegister32));
else if (Scale==2) ObjectCodeEmitByte((byte)(0x40+ScaledRegister32*0x8+BaseRegister32));
else if (Scale==4) ObjectCodeEmitByte((byte)(0x80+ScaledRegister32*0x8+BaseRegister32));
else if (Scale==8) ObjectCodeEmitByte((byte)(0xC0+ScaledRegister32*0x8+BaseRegister32));
else CompilerFault(32);
}
inline
byte ObjectCodeEmitModRM32OffsetRegister32(Register32T Register32,
integer Offset,
Register32T BaseRegister32)
// Send ModRM32Bytes for indexed address mode to object file
// Returns 1st byte of ModRM32 for possible use in EmittedPushRM32 peephole optimization
{ byte ModRM32Byte;
if (Offset==0 && BaseRegister32!=EBP)
{ ModRM32Byte=0x00+Register32*0x8+BaseRegister32;
ObjectCodeEmitByte(ModRM32Byte);
if (BaseRegister32==ESP) ObjectCodeEmitSIB(ESP,1,ESP);
}
else if (Offset>=-128 && Offset<=127)
{ ModRM32Byte=0x40+Register32*0x8+BaseRegister32;
ObjectCodeEmitByte(ModRM32Byte);
if (BaseRegister32==ESP) ObjectCodeEmitSIB(ESP,1,ESP);
ObjectCodeEmitByte((byte)Offset);
}
else { // large offset
ModRM32Byte=0x80+Register32*0x8+BaseRegister32;
ObjectCodeEmitByte(ModRM32Byte);
if (BaseRegister32==ESP) ObjectCodeEmitSIB(ESP,1,ESP);
ObjectCodeEmitDword(Offset);
}
return ModRM32Byte;
}
inline
byte ObjectCodeEmitModRM32OffsetScaledRegister32(Register32T Register32,
integer Offset,
Register32T ScaledRegister32,
natural Scale)
// Send ModRM32Bytes for indexing by a scaled register with no base register to object file
// Returns 1st byte of ModRM32 for possible use in EmittedPushRM32 peephole optimization
{ byte ModRM32Byte=0x00+Register32*0x8+ESP;
ObjectCodeEmitByte(ModRM32Byte); // MOD=00 --> SIB does disp32[index]
ObjectCodeEmitSIB(ScaledRegister32,Scale,EBP);
ObjectCodeEmitDword(Offset);
return ModRM32Byte;
}
inline
byte ObjectCodeEmitModRM32ScaledRegister32OffsetRegister32(Register32T Register32,
Register32T ScaledRegister32,
natural Scale,
integer Offset,
Register32T BaseRegister32)
// Send ModRM32Bytes for indexed address mode to object file
// Returns 1st byte of ModRM32 for possible use in EmittedPushRM32 peephole optimization
// If Scale==0, leave scale and scaled register out of the computation
{ byte ModRM32Byte;
if (Scale==0) ObjectCodeEmitModRM32OffsetRegister32(Register32,Offset,BaseRegister32);
else if (Offset==0 && BaseRegister32!=EBP)
{ ModRM32Byte=0x00+Register32*0x8+ESP;
ObjectCodeEmitByte(ModRM32Byte);
ObjectCodeEmitSIB(ScaledRegister32,Scale,BaseRegister32);
}
else if (Offset>=-128 && Offset<=127)
{ ModRM32Byte=0x40+Register32*0x8+ESP;
ObjectCodeEmitByte(ModRM32Byte);
ObjectCodeEmitSIB(ScaledRegister32,Scale,BaseRegister32);
ObjectCodeEmitByte((byte)Offset);
}
else { // large offset
ModRM32Byte=0x80+Register32*0x8+ESP;
ObjectCodeEmitByte(ModRM32Byte);
ObjectCodeEmitSIB(ScaledRegister32,Scale,BaseRegister32);
ObjectCodeEmitDword(Offset);
}
return ModRM32Byte;
}
inline
void ObjectCodeEmitLeaRegister32OffsetRegister32ScaledPlusBase32(
Register32T Register32Destination,
integer Offset,
Register32T Register32Source,
natural Scale, // 1,2,4 or 8
Register32T Base)
// send "LEA Register32,offset[Register32*Scale+Base]" to object file
{ ObjectCodeEmitLeaOpcode();
ObjectCodeEmitModRM32ScaledRegister32OffsetRegister32(
Register32Destination,Register32Source,Scale,Offset,Base);
}
inline
void ObjectCodeEmitMovRegister32ScaledRegister32OffsetRegister32(Register32T DestinationRegister32,
Register32T ScaledRegister32,
natural Scale,
integer Offset,
Register32T BaseRegister32)
// Emit Mov R32 using scaled index addressing
{ ObjectCodeEmitMovRegister32Opcode();
ObjectCodeEmitModRM32ScaledRegister32OffsetRegister32(DestinationRegister32,
ScaledRegister32,
Scale,
Offset,
BaseRegister32);
}
यह इनलाइन-असेंबली नहीं है, यह इनलाइन मशीन कोड है! –
आपको ऐसा करने की आवश्यकता क्यों है? क्यों न केवल अपने सी कोड से GetCurrentProcess() को कॉल करें? – user9876
@ user9876: मैं एक दूरस्थ (निलंबित) प्रक्रिया में कोड पैच कर रहा हूं; यह प्रोग्राम यूनिक्स सिस्टम पर 'LD_PRELOAD' के रूप में एक समान प्रभाव प्राप्त करता है। –