Files
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

1665 lines
37 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "IMCodeUnits.h"
#include <stdlib.h>
#include <map>
#include "RelocTable.h"
#include "SymbolTable.h"
///////////////////////////////////////////////////////////////////////////////////
// Àü¿ªº¯¼ö
static char szBuffer[128];
static const char * g_szArrRegString[] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "NONE" };
static const char * g_szArrConditionString[] = { "G", "GE", "L", "LE", "E", "NE" };
static CSymbolTable * g_pSymTable = NULL;
static FUNCTABLE * g_pFuncTable = NULL;
static CRelocTable * g_pRelocTable = NULL;
byte arrReg1[] = { 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 };
byte arrReg2[] = { 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78 };
byte arrReg3[] = { 0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8 };
byte arrReg4[] = { 0xC0, 0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF8 };
///////////////////////////////////////////////////////////////////////////////////
//
void SetSymbolTable( CSymbolTable * p )
{
g_pSymTable = p;
}
void SetFuncTable( FUNCTABLE * p )
{
g_pFuncTable = p;
}
void SetRelocTable( CRelocTable * p )
{
g_pRelocTable = p;
}
///////////////////////////////////////////////////////////////////////////////////
//
union Conversion
{
float floatValue;
int intValue;
byte byteValue[4];
Conversion()
: intValue( 0 )
{}
Conversion( int v )
: intValue( v )
{}
Conversion( float f )
: floatValue( f )
{}
Conversion( CONST constID, int offset )
{
eDataType type = g_pSymTable->GetTypeOfConst( int(constID) );
const char * szValue = g_pSymTable->GetNameOfConst( int(constID) );
switch( type )
{
case T_BOOL:
if( strcmp( szValue, "true" ) == 0 )
intValue = 1;
else
intValue = 0;
break;
case T_INT:
{
intValue = strtol( szValue, NULL, 0 );
break;
}
case T_FLOAT:
floatValue = (float)atof( szValue );
break;
case T_STRING:
g_pRelocTable->AddConstString( offset );
intValue = g_pSymTable->GetOffsetOfConst( int(constID ) );
break;
}
}
void Set( byte * p )
{
p[0] = byteValue[0];
p[1] = byteValue[1];
p[2] = byteValue[2];
p[3] = byteValue[3];
}
};
///////////////////////////////////////////////////////////////////////////////////
//
int Code_RM32_Offset( byte * p, byte opByte, int opDigit, int funcID, long addr, int VarOffset )
{
p[0] = opByte;
if( funcID == 0 )
{
p[1] = arrReg1[opDigit] + 5;
Conversion value( VarOffset );
value.Set( p + 2 );
g_pRelocTable->AddGlobalVar( addr + 2 ); //disp32
return 6;
}
else
{
if( VarOffset & 0xffffff00 )
{
p[1] = arrReg3[opDigit] + 5; //disp32[EBP]
Conversion value( VarOffset );
value.Set( p + 2 );
return 6;
}
else
{
p[1] = arrReg2[opDigit] + 5;
p[2] = VarOffset & 0xff; //disp8[EBP]
return 3;
}
}
}
inline
int Code_RM32( byte * p, byte opByte, int opDigit, int funcID, int varID, long addr )
{
int offset = g_pSymTable->GetOffsetOfVar( varID );
return Code_RM32_Offset( p, opByte, opDigit, funcID, addr, offset );
}
long Code_RM32_CodeSize_Offset( int funcID, int VarOffset )
{
if( funcID == 0 || VarOffset & 0xffffff00 )
return 6;
else
return 3;
}
inline
long Code_RM32_CodeSize( int funcID, int varID )
{
int offset = g_pSymTable->GetOffsetOfVar( int(varID) );
return Code_RM32_CodeSize_Offset( funcID, offset );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_call
COP_call::COP_call( FUNC funcID, int line )
: m_funcID( funcID ), m_iLine( line )
{}
int COP_call::ToMachineCode( byte * p )
{
FUNCTABLE::iterator result = g_pFuncTable->find( int(m_funcID) );
if( result == g_pFuncTable->end() )
{
WarningMessage2( m_iLine, "Á¤ÀǵÇÁö ¾ÊÀº ÇÔ¼ö¸¦ È£ÃâÇÏ·Á ½ÃµµÇß½À´Ï´Ù. : %s"
, g_pSymTable->GetTypeStringOfFunc( int(m_funcID) ) );
}
p[0] = 0xe8;
Conversion value( result->second - (m_lAddress+5) );
value.Set( p + 1 );
return 5;
}
long COP_call::Addressing( long addr )
{
m_lAddress = addr;
return addr + 5;
}
void COP_call::Show( MESSAGE_FUNCTION2 Print )
{
Print( "CALL\t\t%s\n", g_pSymTable->GetNameOfFunc( int(m_funcID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_mov
COP_mov::COP_mov( FUNC funcID, VAR varID, eRegister reg )
: m_Type( 0 ), m_funcID( funcID ), m_leftVarID( varID ), m_midArrayIndex( 0 ), m_rightReg( reg )
{}
COP_mov::COP_mov( eRegister reg, FUNC funcID, VAR varID )
: m_Type( 1 ), m_funcID( funcID ), m_leftReg( reg ), m_midArrayIndex( 0 ), m_rightVarID( varID )
{}
COP_mov::COP_mov( eRegister reg, CONST constID )
: m_Type( 2 ), m_funcID( 0 ), m_leftReg( reg ), m_midArrayIndex( 0 ), m_rightConstID( constID )
{}
COP_mov::COP_mov( FUNC funcID, VAR varID, float valuef )
: m_Type( 3 ), m_funcID( funcID ), m_leftVarID( varID ), m_midArrayIndex( 0 ), m_rightValuef( valuef )
{}
COP_mov::COP_mov( eRegister lreg, eRegister rreg )
: m_Type( 4 ), m_funcID( 0 ), m_leftReg( lreg ), m_midArrayIndex( 0 ), m_rightReg( rreg )
{}
COP_mov::COP_mov( eRegister lreg, int value )
: m_Type( 5 ), m_funcID( 0 ), m_leftReg( lreg ), m_midArrayIndex( 0 ), m_rightValue( value )
{}
COP_mov::COP_mov( FUNC funcID, VAR varID, int arrayIndex, eRegister rreg )
: m_Type( 6 ), m_funcID( funcID ), m_leftVarID( varID ), m_midArrayIndex( arrayIndex ), m_rightReg( rreg )
{}
COP_mov::COP_mov( eRegister lreg, FUNC funcID, VAR varID, eRegister indexReg )
: m_Type( 7 ), m_funcID( funcID ), m_leftReg( lreg ), m_midIndexReg( indexReg ), m_rightVarID( varID )
{}
int COP_mov::ToMachineCode( byte * p )
{
switch( m_Type )
{
case 0: //89 / r MOV r/m32,r32 Move r32 to r/m32
case 6:
{
int VarOffset = g_pSymTable->GetOffsetOfVar( int(m_leftVarID) ) + (m_midArrayIndex*4);
return Code_RM32_Offset( p, 0x89, m_rightReg, int(m_funcID), m_lAddress, VarOffset );
}
case 1: //8B / r MOV r32,r/m32 Move r/m32 to r32
return Code_RM32( p, 0x8b, m_leftReg, int(m_funcID), int(m_rightVarID), m_lAddress );
case 2: //B8+ rd MOV r32,imm32 Move imm32 to r32
{
p[0] = 0xb8 + m_leftReg;
Conversion value( m_rightConstID, m_lAddress + 1 );
value.Set( p + 1 );
return 5;
}
case 3: //C7 / 0 MOV r/m32,imm32 Move imm32 to r/m32
{
int codeSize = Code_RM32( p, 0xc7, 0, int(m_funcID), int(m_leftVarID), m_lAddress );
Conversion value( m_rightValuef );
value.Set( p + codeSize );
return codeSize + 4;
}
case 4: //89 / r MOV r/m32,r32 Move r32 to r/m32
{
p[0] = 0x89;
p[1] = arrReg4[m_rightReg] + m_leftReg;
return 2;
}
case 5: //C7 / 0 MOV r/m32,imm32 Move imm32 to r/m32
{
p[0] = 0xc7;
p[1] = 0xc0 + m_leftReg;
Conversion value( m_rightValue );
value.Set( p + 2 );
return 6;
}
case 7:
{
//IMUL m_midIndexReg, -4
//6B / r ib IMUL r32,imm8 doubleword register ¡þ doubleword register * signextended immediate byte
p[0] = 0x6b;
p[1] = 0xc0 + (m_midIndexReg * 9);
p[2] = 0x04;
int offset = g_pSymTable->GetOffsetOfVar( int(m_rightVarID) );
if( m_funcID == 0 )
{
//8B / r MOV r32,r/m32 Move r/m32 to r32
p[3] = 0x8b;
p[4] = arrReg3[m_leftReg] + m_midIndexReg;
Conversion value( offset );
value.Set( p + 5 );
g_pRelocTable->AddGlobalVar( m_lAddress + 5 );
return 9;
}
else
{
//ADD m_midIndexReg, EBP
//03 / r ADD r32,r/m32 Add r/m32 to r32
p[3] = 0x03;
p[4] = arrReg4[m_midIndexReg] + 5;
//8B / r MOV r32,r/m32 Move r/m32 to r32
p[5] = 0x8b;
p[6] = arrReg3[m_leftReg] + m_midIndexReg;
Conversion value( offset );
value.Set( p + 7 );
return 11;
}
break;
}
}
return 0;
}
long COP_mov::Addressing( long addr )
{
m_lAddress = addr;
switch( m_Type )
{
case 0:
case 6:
{
int offset = g_pSymTable->GetOffsetOfVar( int(m_leftVarID) ) + (m_midArrayIndex*4);
return addr + Code_RM32_CodeSize_Offset( int(m_funcID), offset );
}
case 1:
{
int offset = g_pSymTable->GetOffsetOfVar( int(m_rightVarID) ) + (m_midArrayIndex*4);
return addr + Code_RM32_CodeSize_Offset( int(m_funcID), offset );
}
case 2:
return addr + 5;
case 3:
{
int offset = g_pSymTable->GetOffsetOfVar( int(m_leftVarID) ) + (m_midArrayIndex*4);
return addr + 4 + Code_RM32_CodeSize_Offset( int(m_funcID), offset );
}
case 4:
return addr + 2;
case 5:
return addr + 6;
case 7:
return addr + ( m_funcID == 0 ? 9 : 11 );
}
return 0;
}
void COP_mov::Show( MESSAGE_FUNCTION2 Print )
{
Print( "MOV\t\t" );
switch( m_Type )
{
case 0:
Print( "%s, %s\n", g_pSymTable->GetNameOfVar( int(m_leftVarID) )
, g_szArrRegString[m_rightReg] );
break;
case 1:
Print( "%s, %s\n", g_szArrRegString[m_leftReg]
, g_pSymTable->GetNameOfVar( int(m_rightVarID) ) );
break;
case 2:
Print( "%s, %s\n", g_szArrRegString[m_leftReg]
, g_pSymTable->GetNameOfConst( int(m_rightConstID) ) );
break;
case 3:
Print( "%s, %f\n", g_pSymTable->GetNameOfVar( int(m_leftVarID) )
, m_rightValuef );
break;
case 4:
Print( "%s, %s\n", g_szArrRegString[m_leftReg]
, g_szArrRegString[m_rightReg] );
break;
case 5:
Print( "%s, %d\n", g_szArrRegString[m_leftReg]
, m_rightValue );
break;
case 6:
Print( "%s[%d], %s\n", g_pSymTable->GetNameOfVar( int(m_leftVarID) )
, m_midArrayIndex, g_szArrRegString[m_rightReg] );
break;
case 7:
Print( "%s, %s[%s]\n", g_szArrRegString[m_leftReg]
, g_pSymTable->GetNameOfVar( int(m_rightVarID) )
, g_szArrRegString[m_midIndexReg] );
break;
}
}
///////////////////////////////////////////////////////////////////////////////////
// COP_nop
int COP_nop::ToMachineCode( byte * p )
{
p[0] = 0x90;
return 1;
}
long COP_nop::Addressing( long addr )
{
m_lAddress = addr;
return addr + 1;
}
void COP_nop::Show( MESSAGE_FUNCTION2 Print )
{
Print( "NOP\n" );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_add
COP_add::COP_add( eRegister reg, int value )
: m_Type( 0 ), m_leftReg( reg ), m_iValue( value )
{}
COP_add::COP_add( eRegister lreg, eRegister rreg )
: m_Type( 1 ), m_leftReg( lreg ), m_rightReg( rreg )
{}
int COP_add::ToMachineCode( byte * p )
{
switch( m_Type )
{
case 0:
{
//81 /0 id ADD r/m32,imm32 Add imm32 to r/m32
p[0] = 0x81;
p[1] = 0xc0 + m_leftReg;
Conversion value( m_iValue );
value.Set( p + 2 );
return 6;
}
case 1:
//03 / r ADD r32,r/m32 Add r/m32 to r32
p[0] = 0x03;
p[1] = arrReg4[m_leftReg] + m_rightReg;
return 2;
}
return 0;
}
long COP_add::Addressing( long addr )
{
m_lAddress = addr;
switch( m_Type )
{
case 0: return addr + 6;
case 1: return addr + 2;
}
return 0;
}
void COP_add::Show( MESSAGE_FUNCTION2 Print )
{
Print( "ADD\t\t" );
switch( m_Type )
{
case 0: Print( "%s, %d\n", g_szArrRegString[m_leftReg], m_iValue );
break;
case 1: Print( "%s, %s\n", g_szArrRegString[m_leftReg], g_szArrRegString[m_rightReg] );
break;
}
}
///////////////////////////////////////////////////////////////////////////////////
// COP_sub
COP_sub::COP_sub( eRegister reg, int value )
: m_Type( 0 ), m_leftReg( reg ), m_iValue( value )
{}
COP_sub::COP_sub( eRegister lreg, eRegister rreg )
: m_Type( 1 ), m_leftReg( lreg ), m_rightReg( rreg )
{}
int COP_sub::ToMachineCode( byte * p )
{
switch( m_Type )
{
case 0:
{
//81 /5 id SUB r/m32,imm32 Subtract imm32 from r/m32
p[0] = 0x81;
p[1] = 0xe8 + m_leftReg;
Conversion value( m_iValue );
value.Set( p + 2 );
return 6;
}
case 1:
//2B / r SUB r32,r/m32 Subtract r/m32 from r32
p[0] = 0x2b;
p[1] = arrReg4[m_leftReg] + m_rightReg;
return 2;
}
return 0;
}
long COP_sub::Addressing( long addr )
{
m_lAddress = addr;
switch( m_Type )
{
case 0:
return addr + 6;
case 1:
return addr + 2;
}
return 0;
}
void COP_sub::Show( MESSAGE_FUNCTION2 Print )
{
Print( "SUB\t\t" );
switch( m_Type )
{
case 0:
Print( "%s, %d\n", g_szArrRegString[m_leftReg], m_iValue );
break;
case 1:
Print( "%s, %s\n", g_szArrRegString[m_leftReg], g_szArrRegString[m_rightReg] );
break;
}
}
///////////////////////////////////////////////////////////////////////////////////
// COP_imul
COP_imul::COP_imul( eRegister lreg, eRegister rreg )
: m_leftReg( lreg ), m_rightReg( rreg )
{}
int COP_imul::ToMachineCode( byte * p )
{
//0F AF / r IMUL r32,r/m32 doubleword register <- doubleword register * r/m doubleword
p[0] = 0x0f;
p[1] = 0xaf;
p[2] = arrReg4[m_leftReg] + m_rightReg;
return 3;
}
long COP_imul::Addressing( long addr )
{
m_lAddress = addr;
return addr + 3;
}
void COP_imul::Show( MESSAGE_FUNCTION2 Print )
{
Print( "IMUL\t\t" );
Print( "%s, %s\n", g_szArrRegString[m_leftReg], g_szArrRegString[m_rightReg] );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_idiv
COP_idiv::COP_idiv( eRegister rreg )
: m_rightReg( rreg )
{
}
int COP_idiv::ToMachineCode( byte * p )
{
//99 CDQ EDX:EAX ¡þ sign-extend of EAX
p[0] = 0x99;
//F7 /7 IDIV r/m32 Signed divide EDX:EAX (where EDX must contain sign-extension of EAX)
//by r/m doubleword. (Results:EAX=Quotient, EDX=Remainder)
p[1] = 0xf7;
p[2] = 0xf8 + m_rightReg;
return 3;
}
long COP_idiv::Addressing( long addr )
{
m_lAddress = addr;
return addr + 3;
}
void COP_idiv::Show( MESSAGE_FUNCTION2 Print )
{
Print( "IDIV\t\t" );
Print( "%s\n", g_szArrRegString[m_rightReg] );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_push
COP_push::COP_push( eRegister reg )
: m_Reg( reg )
{}
int COP_push::ToMachineCode( byte * p )
{
p[0] = 0x50 + m_Reg;
return 1;
}
long COP_push::Addressing( long addr )
{
m_lAddress = addr;
return addr + 1;
}
void COP_push::Show( MESSAGE_FUNCTION2 Print )
{
Print( "PUSH\t\t%s\n", g_szArrRegString[m_Reg] );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_pop
COP_pop::COP_pop( eRegister reg )
: m_Reg( reg )
{}
int COP_pop::ToMachineCode( byte * p )
{
p[0] = 0x58 + m_Reg; //58+ rd POP r32 Pop top of stack into r32; increment stack pointer
return 1;
}
long COP_pop::Addressing( long addr )
{
m_lAddress = addr;
return addr + 1;
}
void COP_pop::Show( MESSAGE_FUNCTION2 Print )
{
Print( "POP\t\t%s\n", g_szArrRegString[m_Reg] );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_jmp
COP_jmp::COP_jmp()
: m_pJumpTarget( 0 )
{
}
COP_jmp::COP_jmp( IOPCode * pJmpTarget )
: m_pJumpTarget( pJmpTarget )
{
}
COP_jmp::~COP_jmp()
{
}
int COP_jmp::ToMachineCode( byte * p )
{
//E9 cd JMP rel32 Jump near, relative, displacement relative to next instruction
p[0] = 0xe9;
Conversion i = m_pJumpTarget->m_lAddress - ( m_lAddress + 5 );
i.Set( p + 1 );
return 5;
}
long COP_jmp::Addressing( long addr )
{
m_lAddress = addr;
return addr + 5;
}
void COP_jmp::Show( MESSAGE_FUNCTION2 Print )
{
Print( "JMP\t\t%X\n", m_pJumpTarget->m_lAddress );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_jcc
COP_jcc::COP_jcc( eCondition condition )
: m_Condition( condition )
{}
int COP_jcc::ToMachineCode( byte * p )
{
p[0] = 0x0f;
Conversion i = m_pJumpTarget->m_lAddress - ( m_lAddress + 6 );
i.Set( p + 2 );
//¸ðµÎ relative Á¡ÇÁÀÓ
switch( m_Condition )
{
case G:
//0F 8F cw/cd JG rel16/32 Jump near if greater (ZF=0 and SF=OF)
p[1] = 0x8f;
break;
case GE:
//0F 8D cw/cd JGE rel16/32 Jump near if greater or equal (SF=OF)
p[1] = 0x8d;
break;
case L:
//0F 8C cw/cd JL rel16/32 Jump near if less (SF<>OF)
p[1] = 0x8c;
break;
case LE:
//0F 8E cw/cd JLE rel16/32 Jump near if less or equal (ZF=1 or SF<>OF)
p[1] = 0x8e;
break;
case E:
//0F 84 cw/cd JE rel16/32 Jump near if equal (ZF=1)
p[1] = 0x84;
break;
case NE:
//0F 85 cw/cd JNE rel16/32 Jump near if not equal (ZF=0)
p[1] = 0x85;
break;
}
return 6;
}
long COP_jcc::Addressing( long addr )
{
m_lAddress = addr;
return addr + 6;
}
void COP_jcc::Show( MESSAGE_FUNCTION2 Print )
{
Print( "J%s\t\t%X\n", g_szArrConditionString[m_Condition], m_pJumpTarget->m_lAddress );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_jmpmark
COP_jmpmark::COP_jmpmark()
: m_pJumpSrc( 0 )
{}
COP_jmpmark::COP_jmpmark( COP_jmp * pOPjmp )
: m_pJumpSrc( pOPjmp )
{
pOPjmp->m_pJumpTarget = this;
}
int COP_jmpmark::ToMachineCode( byte * )
{
//Äڵ带 ¸¸µéÁö ¾ÊÀ½.
return 0;
}
long COP_jmpmark::Addressing( long addr )
{
m_lAddress = addr;
//ÁÖ¼Ò¸¦ Áõ°¡½ÃŰÁö ¾ÊÀ½À¸·Î½á ´ÙÀ½ instruction°ú °°Àº ÁÖ¼Ò¸¦ °¡Áü.
return addr;
}
void COP_jmpmark::Show( MESSAGE_FUNCTION2 Print )
{
if( m_pJumpSrc )
Print( "JMPMARK\t\t%X\n", m_pJumpSrc->m_lAddress );
else
Print( "JMPMARK\t\t\n" );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_cmp
COP_cmp::COP_cmp( FUNC funcID, VAR lvarID, CONST rconstID )
: m_Type( 0 ), m_funcID( funcID ), m_leftVarID( lvarID ), m_rightConstID( rconstID )
{}
COP_cmp::COP_cmp( eRegister lreg, byte value )
: m_Type( 1 ), m_funcID( 0 ), m_leftReg( lreg ), m_rightValue( value )
{}
COP_cmp::COP_cmp( eRegister lreg, eRegister rreg )
: m_Type( 2 ), m_funcID( 0 ), m_leftReg( lreg ), m_rightReg( rreg )
{}
int COP_cmp::ToMachineCode( byte * p )
{
switch( m_Type )
{
case 0:
{
p[0] = 0x81;
int offset = g_pSymTable->GetOffsetOfVar( int(m_leftVarID) );
if( m_funcID == 0 )
{
p[1] = 0x3d;
Conversion value( offset );
value.Set( p + 2 );
g_pRelocTable->AddGlobalVar( m_lAddress + 2 );
Conversion value2( m_rightConstID, m_lAddress + 6 );
value2.Set( p + 6 );
return 10;
}
else
{
if( offset & 0xffffff00 )
{
p[1] = 0xbd;
Conversion value( offset );
value.Set( p + 2 );
Conversion value2( m_rightConstID, m_lAddress + 6 );
value2.Set( p + 6 );
return 10;
}
else
{
p[1] = 0x7d;
p[2] = offset & 0xff;
Conversion value2( m_rightConstID, m_lAddress + 3 );
value2.Set( p + 3 );
return 7;
}
}
break;
}
case 1:
//83 /7 ib CMP r/m32,imm8 Compare imm8 with r/m32
p[0] = 0x83;
p[1] = 0xf8 + m_leftReg;
p[2] = m_rightValue;
return 3;
case 2:
//3B / r CMP r32,r/m32 Compare r/m32 with r32
p[0] = 0x3b;
p[1] = arrReg4[m_leftReg] + m_rightReg;
return 2;
}
return 0;
}
long COP_cmp::Addressing( long addr )
{
m_lAddress = addr;
switch( m_Type )
{
case 0:
{
int offset = g_pSymTable->GetOffsetOfVar( int(m_leftVarID) );
if( m_funcID == 0 || offset & 0xffffff00 )
return addr + 10;
else
return addr + 7;
break;
}
case 1: return addr + 3;
case 2: return addr + 2;
}
return 0;
}
void COP_cmp::Show( MESSAGE_FUNCTION2 Print )
{
switch( m_Type )
{
case 0:
Print( "CMP\t\t%s, %s\n", g_pSymTable->GetNameOfVar( int(m_leftVarID) )
, g_pSymTable->GetNameOfConst( int(m_rightConstID) ) );
break;
case 1:
Print( "CMP\t\t%s, %d\n", g_szArrRegString[m_leftReg], m_rightValue );
break;
case 2:
Print( "CMP\t\t%s, %s\n", g_szArrRegString[m_leftReg], g_szArrRegString[m_rightReg] );
break;
}
}
///////////////////////////////////////////////////////////////////////////////////
// COP_ret
int COP_ret::ToMachineCode( byte * p )
{
//C3 RET Near return to calling procedure
p[0] = 0xc3;
return 1;
}
long COP_ret::Addressing( long addr )
{
m_lAddress = addr;
return addr + 1;
}
void COP_ret::Show( MESSAGE_FUNCTION2 Print )
{
Print( "RET\n" );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_xor
COP_xor::COP_xor( eRegister lreg, eRegister rreg )
: m_leftReg( lreg ), m_rightReg( rreg )
{}
int COP_xor::ToMachineCode( byte * p )
{
//33 / r XOR r32,r/m32 r8 XOR r/m8
p[0] = 0x33;
p[1] = arrReg4[m_leftReg] + m_rightReg;
return 2;
}
long COP_xor::Addressing( long addr )
{
m_lAddress = addr;
return addr + 2;
}
void COP_xor::Show( MESSAGE_FUNCTION2 Print )
{
Print( "XOR\t\t%s, %s\n", g_szArrRegString[m_leftReg], g_szArrRegString[m_rightReg] );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_setcc
COP_setcc::COP_setcc( eCondition condition, eRegister lreg )
: m_Condition( condition ), m_Reg( lreg )
{
if( m_Reg > EBX )
ScriptSystemError( "setcc ¸í·É¿¡ EAX, ECX, EDX, EBX¿ÜÀÇ ·¹Áö½ºÅ͸¦ ÁöÁ¤Çß½À´Ï´Ù." );
}
int COP_setcc::ToMachineCode( byte * p )
{
//xor reg, reg¸¦ ¾²¸é EFLAG ·¹Áö½ºÅÍ °ªÀ» ¹Ù²ã¹ö¸®¹Ç·Î ¾²¸é ¾ÈµÊ.
//B8+ rd MOV r32,imm32 Move imm32 to r32
p[0] = 0xb8 + m_Reg;
Conversion value( 0 );
value.Set( p + 1 );
//setcc r/m8
p[5] = 0x0f;
switch( m_Condition )
{
case G: //0F 9F SETG r/m8 Set byte if greater (ZF=0 and SF=OF)
p[6] = 0x9f;
break;
case GE: //0F 9D SETGE r/m8 Set byte if greater or equal (SF=OF)
p[6] = 0x9d;
break;
case L: //0F 9C SETL r/m8 Set byte if less (SF<>OF)
p[6] = 0x9c;
break;
case LE: //0F 9E SETLE r/m8 Set byte if less or equal (ZF=1 or SF<>OF)
p[6] = 0x9e;
break;
case E: //0F 94 SETE r/m8 Set byte if equal (ZF=1)
p[6] = 0x94;
break;
case NE: //0F 95 SETNE r/m8 Set byte if not equal (ZF=0)
p[6] = 0x95;
break;
}
p[7] = 0xc0 + m_Reg;
return 8;
}
long COP_setcc::Addressing( long addr )
{
m_lAddress = addr;
return addr + 8;
}
void COP_setcc::Show( MESSAGE_FUNCTION2 Print )
{
Print( "SET%s\t\t%s\n", g_szArrConditionString[m_Condition], g_szArrRegString[m_Reg] );
}
///////////////////////////////////////////////////////////////////////////////////
// COP_int3
int COP_int3::ToMachineCode( byte * p )
{
p[0] = 0xcc;
return 1;
}
long COP_int3::Addressing( long addr )
{
m_lAddress = addr;
return addr + 1;
}
void COP_int3::Show( MESSAGE_FUNCTION2 Print )
{
Print( "INT\t\t3\n" );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_fld::COP_fld( FUNC funcID, VAR varID )
: m_funcID( funcID ), m_varID( varID )
{}
int COP_fld::ToMachineCode( byte * p )
{
//D9 /0 FLD m32real Push m32real onto the FPU register stack.
return Code_RM32( p, 0xd9, 0, int(m_funcID), int(m_varID), m_lAddress );
}
long COP_fld::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
}
void COP_fld::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FLD\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_fadd::COP_fadd( FUNC funcID, VAR varID )
: m_funcID( funcID ), m_varID( varID )
{}
int COP_fadd::ToMachineCode( byte * p )
{
//D8 /0 FADD m32 real Add m32real to ST(0) and store result in ST(0)
return Code_RM32( p, 0xd8, 0, int(m_funcID), int(m_varID), m_lAddress );
}
long COP_fadd::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
}
void COP_fadd::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FADD\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_fsub::COP_fsub( FUNC funcID, VAR varID )
: m_funcID( funcID ), m_varID( varID )
{}
int COP_fsub::ToMachineCode( byte * p )
{
//D8 /4 FSUB m32real Subtract m32real from ST(0) and store result in ST(0)
return Code_RM32( p, 0xd8, 4, int(m_funcID), int(m_varID), m_lAddress );
}
long COP_fsub::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
}
void COP_fsub::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FSUB\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_fmul::COP_fmul( FUNC funcID, VAR varID )
: m_funcID( funcID ), m_varID( varID )
{}
int COP_fmul::ToMachineCode( byte * p )
{
//D8 /1 FMUL m32real Multiply ST(0) by m32real and store result in ST(0)
return Code_RM32( p, 0xd8, 1, int(m_funcID), int(m_varID), m_lAddress );
}
long COP_fmul::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
}
void COP_fmul::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FMUL\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_fdiv::COP_fdiv( FUNC funcID, VAR varID )
: m_funcID( funcID), m_varID( varID )
{}
int COP_fdiv::ToMachineCode( byte * p )
{
//D8 /6 FDIV m32real Divide ST(0) by m32real and store result in ST(0)
return Code_RM32( p, 0xd8, 6, int(m_funcID), int(m_varID), m_lAddress );
}
long COP_fdiv::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
}
void COP_fdiv::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FDIV\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_fstp::COP_fstp( FUNC funcID, VAR varID, bool bDouble )
: m_funcID( funcID ), m_varID( varID ), m_bDouble( bDouble )
{}
int COP_fstp::ToMachineCode( byte * p )
{
if( m_bDouble )
{
//DD /3 FSTP m64real Copy ST(0) to m64real and pop register stack
int offset = g_pSymTable->GetOffsetOfVar( int(m_varID) );
return Code_RM32_Offset( p, 0xdd, 3, int(m_funcID), m_lAddress, offset - 4 );
}
else
{
//D9 /3 FSTP m32real Copy ST(0) to m32real and pop register stack
return Code_RM32( p, 0xd9, 3, int(m_funcID), int(m_varID), m_lAddress );
}
}
long COP_fstp::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
}
void COP_fstp::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FSTP\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_fcomp::COP_fcomp( FUNC funcID, VAR varID )
: m_funcID( funcID ), m_varID( varID )
{}
int COP_fcomp::ToMachineCode( byte * p )
{
//D8 /3 FCOMP m32real Compare ST(0) with m32real and pop register stack.
return Code_RM32( p, 0xd8, 3, int(m_funcID), int(m_varID), m_lAddress );
}
long COP_fcomp::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
}
void COP_fcomp::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FCOMP\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
int COP_fnstsw_ax::ToMachineCode( byte * p )
{
p[0] = 0xdf;
p[1] = 0xe0;
return 2;
}
long COP_fnstsw_ax::Addressing( long addr )
{
m_lAddress = addr;
return addr + 2;
}
void COP_fnstsw_ax::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FNSTSW\t\tAX\n" );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_test_ah::COP_test_ah( byte Value8 )
: m_Value8( Value8 )
{}
int COP_test_ah::ToMachineCode( byte * p )
{
//F6 /0 ib TEST r/m8,imm8 AND imm8 with r/m8; set SF, ZF, PF according to result
p[0] = 0xf6;
p[1] = 0xc4;
p[2] = m_Value8;
return 3;
}
long COP_test_ah::Addressing( long addr )
{
m_lAddress = addr;
return addr + 3;
}
void COP_test_ah::Show( MESSAGE_FUNCTION2 Print )
{
Print( "TEST\t\tAH, %d\n", m_Value8 );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_itoa::COP_itoa( eRegister leftReg, VAR stringBuffer )
: m_leftReg( leftReg ), m_StringBuffer( stringBuffer )
{}
int COP_itoa::ToMachineCode( byte * p )
{
//itoaÀÇ ¼¼¹øÂ° ÀÎÀÚ(10) push
p[0] = 0x6a; //6A PUSH imm8 Push imm8
p[1] = 0x0a;
//itoaÀÇ µÎ¹øÂ° ÀÎÀÚ(¹®ÀÚ¿­ ¹öÆÛ) push
p[2] = 0xff; //FF /6 PUSH r/m32 Push r/m32
p[3] = 0x35;
if( g_pSymTable->GetTypeOfVar( int(m_StringBuffer) ) != T_STRING )
ScriptSystemError( "À̰ÍÀº String Buffer°¡ ¾Æ´ÏÀÚ³ª??!! ( COP_itoa::ToMachineCode() )" );
int StrBufOffset = g_pSymTable->GetOffsetOfVar( int(m_StringBuffer) );
Conversion value( StrBufOffset );
g_pRelocTable->AddGlobalVar( m_lAddress + 4 );
value.Set( p + 4 );
//itoaÀÇ Ã¹¹øÂ° ÀÎÀÚ(Á¤¼ö) push
p[8] = 0x50 + m_leftReg; //50+ rd PUSH r32 Push r32
//call itoa
p[9] = 0xb8 + m_leftReg; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_ITOA, m_lAddress + 10 );
Conversion value2( 0 );
value.Set( p + 10 );
p[14] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[15] = 0xd0 + m_leftReg;
//add esp, 12
p[16] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[17] = 0xc4;
p[18] = 0x0c;
return 19;
}
long COP_itoa::Addressing( long addr )
{
m_lAddress = addr;
return addr + 19;
}
void COP_itoa::Show( MESSAGE_FUNCTION2 Print )
{
Print( "ITOA\t\t%s, %s\n", g_szArrRegString[m_leftReg]
, g_pSymTable->GetNameOfConst( int(m_StringBuffer) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_ftoa::COP_ftoa( eRegister freeReg, VAR DoubleVar, VAR stringBuffer )
: m_freeReg( freeReg ), m_DoubleVar( DoubleVar ), m_StringBuffer( stringBuffer )
{}
int COP_ftoa::ToMachineCode( byte * p )
{
int n = 0;
//gvctÀÇ ¼¼ ¹øÂ° ÀÎÀÚ(¹®ÀÚ¿­ ¹öÆÛ) push
p[n++] = 0xff; //FF /6 PUSH r/m32 Push r/m32
p[n++] = 0x35;
if( g_pSymTable->GetTypeOfVar( int(m_StringBuffer) ) != T_STRING )
ScriptSystemError( "À̰ÍÀº String Buffer°¡ ¾Æ´ÏÀÚ³ª??!! ( COP_ftoa::ToMachineCode() )" );
int StrBufOffset = g_pSymTable->GetOffsetOfVar( int(m_StringBuffer) );
Conversion value( StrBufOffset );
g_pRelocTable->AddGlobalVar( m_lAddress + n );
value.Set( p + n );
n += 4;
//gvctÀÇ µÎ ¹øÂ° ÀÎÀÚ(À¯È¿ ¼ýÀÚ) push
p[n++] = 0x6a; //6A PUSH imm8 Push imm8
p[n++] = 0x08; //À¯È¿ ¼ýÀÚ¸¦ 15·Î ¼³Á¤.
//gvctÀÇ Ã¹ ¹øÂ° ÀÎÀÚ(½Ç¼ö°ª) push -- doubleÀ» ÀÎÀÚ·Î ¹ÞÀ¸¹Ç·Î µÎ¹ø pushÇÔ.
//FF /6 PUSH r/m32 Push r/m32
n += Code_RM32( p + n, 0xff, 6, 0, int(m_DoubleVar), m_lAddress + n );
int offset = g_pSymTable->GetOffsetOfVar( int(m_DoubleVar) );
n += Code_RM32_Offset( p + n, 0xff, 6, 0, m_lAddress + n, offset - 4 );
//call gvct
p[n++] = 0xb8 + m_freeReg; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_GCVT, m_lAddress + n );
Conversion value2( 0 );
value2.Set( p + n );
n += 4;
p[n++] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[n++] = 0xd0 + m_freeReg;
//add esp, 16
p[n++] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[n++] = 0xc4;
p[n++] = 0x10;
return n;
}
long COP_ftoa::Addressing( long addr )
{
m_lAddress = addr;
return addr + Code_RM32_CodeSize( 0, int(m_DoubleVar) ) * 2 + 18;
}
void COP_ftoa::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FTOA\t\t%s, %s\n", g_pSymTable->GetNameOfVar( int(m_DoubleVar) )
, g_pSymTable->GetNameOfVar( int(m_StringBuffer) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_malloc::COP_malloc( eRegister reg )
: m_Reg( reg )
{}
int COP_malloc::ToMachineCode( byte * p )
{
for( int i = 0; i < 24; i++ )
{
p[i] = 0x90;
}
//mallocÀÇ Ã¹¹øÂ° ÀÎÀÚ(ÇÒ´çÇÒ ¾ç) push
p[0] = 0x50 + m_Reg; //50+ rd PUSH r32 Push r32
//call malloc
p[1] = 0xb8 + m_Reg; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_MALLOC, m_lAddress + 2 );
Conversion value( 0 );
value.Set( p + 2 );
p[6] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[7] = 0xd0 + m_Reg;
//add esp, 4
p[8] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[9] = 0xc4;
p[10] = 0x04;
p[11] = 0x50 + EAX;
//RegisterAllocatedMemory È£Ãâ
p[12] = 0x50 + ESI; //push ESI
p[13] = 0x50 + EAX; //push EAX
p[14] = 0xb8 + ESI; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_REGISTERALLOCATEDMEMORY, m_lAddress + 15 );
p[19] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[20] = 0xd0 + ESI;
p[21] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[22] = 0xc4; //add esp, 4
p[23] = 0x04;
p[24] = 0x58 + ESI; //pop ESI
p[25] = 0x58 + EAX; //58+ rd POP r32 Pop top of stack into r32; increment stack pointer
return 26;
}
long COP_malloc::Addressing( long addr )
{
m_lAddress = addr;
return addr + 26;
}
void COP_malloc::Show( MESSAGE_FUNCTION2 Print )
{
Print( "MALLOC\t\t%s\n", g_szArrRegString[m_Reg] );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_free::COP_free( FUNC funcID, VAR varID )
: m_funcID( funcID ), m_varID( varID )
{}
int COP_free::ToMachineCode( byte * p )
{
//freeÀÇ Ã¹¹øÂ° ÀÎÀÚ(¸Þ¸ð¸® ÁÖ¼Ò) push //FF /6 PUSH r/m32 Push r/m32
int n = Code_RM32( p, 0xff, 6, int(m_funcID), int(m_varID), m_lAddress );
//call free
p[n++] = 0xb8 + ECX; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_FREE, m_lAddress + n );
Conversion value( 0 );
value.Set( p + n );
n += 4;
p[n++] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[n++] = 0xd0 + ECX;
//add esp, 4
p[n++] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[n++] = 0xc4;
p[n++] = 0x04;
//UnregisterAllocatedMemory È£Ãâ
n += Code_RM32( p + n, 0xff, 6, int(m_funcID), int(m_varID), m_lAddress + n );
p[n++] = 0xb8 + ECX; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_UNREGISTERALLOCATEDMEMORY, m_lAddress + n );
n += 4;
p[n++] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[n++] = 0xd0 + ECX;
p[n++] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[n++] = 0xc4;
p[n++] = 0x04;
return n;
}
long COP_free::Addressing( long addr )
{
int n = Code_RM32_CodeSize( int(m_funcID), int(m_varID) );
m_lAddress = addr;
return addr + ((n + 10)*2);
}
void COP_free::Show( MESSAGE_FUNCTION2 Print )
{
Print( "FREE\t\t%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_strcpy::COP_strcpy( eRegister lreg, eRegister rreg )
: m_type( 0 ), m_leftReg( lreg ), m_rightReg( rreg )
{}
COP_strcpy::COP_strcpy( eRegister lreg, FUNC funcID, VAR varID )
: m_type( 1 ), m_leftReg( lreg ), m_funcID( funcID ), m_varID( varID )
{}
int COP_strcpy::ToMachineCode( byte * p )
{
int n = 0;
//strcpyÀÇ µÎ¹øÂ° ÀÎÀÚ(¿øº» ¹®ÀÚ¿­ÁÖ¼Ò) push
if( m_type == 0 )
{
//50+ rd PUSH r32 Push r32
p[n++] = 0x50 + m_rightReg;
}
else
{
//FF /6 PUSH r/m32 Push r/m32
n += Code_RM32( p, 0xff, 6, int(m_funcID), int(m_varID), m_lAddress );
}
//strcpyÀÇ Ã¹¹øÂ° ÀÎÀÚ(´ë»ó ¹®ÀÚ¿­ ÁÖ¼Ò) push
p[n++] = 0x50 + m_leftReg;
//call strcpy
p[n++] = 0xb8 + m_leftReg; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_STRCPY, m_lAddress + n );
Conversion value( 0 );
value.Set( p + n );
n += 4;
p[n++] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[n++] = 0xd0 + m_leftReg;
//add esp, 8
p[n++] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[n++] = 0xc4;
p[n++] = 0x08;
return n;
}
long COP_strcpy::Addressing( long addr )
{
m_lAddress = addr;
if( m_type == 0 )
return addr + 12;
else
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) ) + 11;
}
void COP_strcpy::Show( MESSAGE_FUNCTION2 Print )
{
Print( "STRCPY\t\t%s,", g_szArrRegString[m_leftReg] );
if( m_type == 0 )
Print( " %s\n", g_szArrRegString[m_rightReg] );
else
Print( " %s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_strcmp::COP_strcmp( eRegister lreg, eRegister rreg )
: m_leftReg( lreg ), m_rightReg( rreg )
{}
int COP_strcmp::ToMachineCode( byte * p )
{
//strcmpÀÇ µÎ¹øÂ° ÀÎÀÚ push
p[0] = 0x50 + m_rightReg; //50+ rd PUSH r32 Push r32
//strcmpÀÇ Ã¹¹øÂ° ÀÎÀÚ push
p[1] = 0x50 + m_leftReg; //50+ rd PUSH r32 Push r32
//call strcmp
p[2] = 0xb8 + m_leftReg; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_STRCMP, m_lAddress + 3 );
Conversion value( 0 );
value.Set( p + 3 );
p[7] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[8] = 0xd0 + m_leftReg;
//add esp, 8
p[9] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[10] = 0xc4;
p[11] = 0x08;
return 12;
}
long COP_strcmp::Addressing( long addr )
{
m_lAddress = addr;
return addr + 12;
}
void COP_strcmp::Show( MESSAGE_FUNCTION2 Print )
{
Print( "STRCMP\t\t%s, %s\n", g_szArrRegString[m_leftReg], g_szArrRegString[m_rightReg] );
}
///////////////////////////////////////////////////////////////////////////////////
//
COP_strlen::COP_strlen( eRegister reg )
: m_type( 0 ), m_Reg( reg )
{}
COP_strlen::COP_strlen( FUNC funcID, VAR varID )
: m_type( 1 ), m_funcID( funcID ), m_varID( varID )
{}
int COP_strlen::ToMachineCode( byte * p )
{
//strcpyÀÇ Ã¹¹øÂ° ÀÎÀÚ(¹®ÀÚ¿­ÀÇ ÁÖ¼Ò) push
int n = 0;
if( m_type == 0 )
{
//50+ rd PUSH r32 Push r32
p[n++] = 0x50 + m_Reg;
}
else
{
//FF /6 PUSH r/m32 Push r/m32
n += Code_RM32( p, 0xff, 6, int(m_funcID), int(m_varID), m_lAddress );
}
//call strlen
p[n++] = 0xb8 + EAX; //B8+ rd MOV r32,imm32 Move imm32 to r32
g_pRelocTable->AddFuncBind( FUNC_STRLEN, m_lAddress + n );
Conversion value( 0 );
value.Set( p + n );
n += 4;
p[n++] = 0xff; //FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32
p[n++] = 0xd0 + EAX;
//add esp, 4
p[n++] = 0x83; //83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32
p[n++] = 0xc4;
p[n++] = 0x04;
return n;
}
long COP_strlen::Addressing( long addr )
{
m_lAddress = addr;
if( m_type == 0 )
return addr + 11;
else
return addr + Code_RM32_CodeSize( int(m_funcID), int(m_varID) ) + 10;
}
void COP_strlen::Show( MESSAGE_FUNCTION2 Print )
{
Print( "STRLEN\t\t" );
if( m_type == 0 )
Print( "%s\n", g_szArrRegString[m_Reg] );
else
Print( "%s\n", g_pSymTable->GetNameOfVar( int(m_varID) ) );
}
///////////////////////////////////////////////////////////////////////////////////