
ææ°ã®ã³ã³ãã€ã©ã¯ãã³ãŒãã®æé©åã«éåžžã«åªããŠããŸãã å®è¡ãããªãæ¡ä»¶ä»ãé·ç§»ãåé€ãã宿°åŒãèšç®ããç¡æå³ãªç®è¡æŒç®ïŒ1ã®ä¹ç®ã0ã®å ç®ïŒãåãé€ããŸãã ã³ã³ãã€ã«æã«æ¢ç¥ã®ããŒã¿ãæäœããŸãã
åŠçãããããŒã¿ã«é¢ããæ
å ±ã®å®è¡æã«ã¯ãã¯ããã«å€ããªããŸãã ããã«åºã¥ããŠã远å ã®æé©åãå®è¡ããããã°ã©ã ãé«éåã§ããŸãã
ç¹å®ã®ã±ãŒã¹çšã«æé©åãããã¢ã«ãŽãªãºã ã¯ãæ®éçãªã¢ã«ãŽãªãºã ãããåžžã«é«éã«åäœããŸãïŒå°ãªããšãé
ãã¯ãããŸããïŒã
å
¥åããŒã¿ã®åã»ããã«å¯ŸããŠããã®ããŒã¿ãåŠçããããã®æé©ãªã¢ã«ãŽãªãºã ãçæãããšã©ããªããŸããïŒ
æããã«ãå®è¡æéã®äžéšã¯æé©åã«è²»ããããŸãããæé©åãããã³ãŒããé »ç¹ã«å®è¡ãããå Žåãã³ã¹ãã¯å©åã§è¿æžãããŸãã
ããã¯æè¡çã«ã©ã®ããã«è¡ããŸããïŒ éåžžã«ç°¡åã§ã-å¿
èŠãªã³ãŒããçæããããã°ã©ã ã«ããã³ã³ãã€ã©ãå«ãŸããŠããŸãã ãã®ã¢ã€ãã¢ã¯æ°ãããã®ã§ã¯ãªãããã®æè¡ã¯ãã©ã³ã¿ã€ã ã³ã³ãã€ã«ããŸãã¯JITã³ã³ãã€ã«ãšåŒã°ããŸãã JITã³ã³ãã€ã«ã¯ãä»®æ³ãã·ã³ããã³ããã°ã©ãã³ã°èšèªã®ã€ã³ã¿ãŒããªã¿ãŒã§éèŠãªåœ¹å²ãæãããŸãã é »ç¹ã«äœ¿çšãããã³ãŒãïŒãŸãã¯ãã€ãã³ãŒãïŒã®ã»ã¯ã·ã§ã³ããã·ã³åœä»€ã«å€æããããããããã©ãŒãã³ã¹ã倧å¹
ã«åäžããŸãã
JavaãPythonãCïŒãJavaScriptãFlash ActionScriptã¯ã䜿çšãããèšèªã®äžå®å
šãªïŒå®å
šã«äžå®å
šãªïŒãªã¹ãã§ãã ãã®æè¡ã䜿çšããŠç¹å®ã®åé¡ã解決ããäœãèµ·ããããææ¡ããŸãã
ææŠãã
ã¿ã¹ã¯ã¯ãæ°åŒã®ã€ã³ã¿ãŒããªã¿ãŒã®å®è£
ãååŸããããšã§ãã å
¥åã«ã¯æ¬¡ã®åœ¢åŒã®è¡ããããŸã
æ°å€ã¯xã®å€ã§ãã åºåã¯æ°å€ã§ããå¿
èŠããããŸã-ãã®xã®å€ã®åŒã®å€ã ç°¡åã«ããããã«ãã+ããã-ããã*ããã/ãã®4ã€ã®æŒç®åã®ã¿ãåŠçããŸãã
ãã®æ®µéã§ã¯ãæååã¯ããã衚çŸããã®ã«æã䟿å©ãªæ¹æ³ã§ã¯ãªãããããã®åŒãã©ã®ããã«ã³ã³ãã€ã«ã§ãããã¯ãŸã æç¢ºã§ã¯ãããŸããã åæãšèšç®ã«ã¯ãè§£æããªãŒããã®å Žåã¯ãã€ããªããªãŒã®æ¹ãé©ããŠããŸãã
å
ã®åŒã®å Žåãæ¬¡ã®ããã«ãªããŸãã
ããªãŒã®åããŒãã¯æŒç®åã§ããããã®åã¯ãªãã©ã³ãã§ãã ããªãŒã®èã¯å®æ°ãšå€æ°ã§ãã
ãã®ãããªããªãŒãæ§ç¯ããããã®æãç°¡åãªã¢ã«ãŽãªãºã ã¯ãååž°éäžã§ããåæ®µéã§ãåªå
床ãæãäœãæŒç®åãèŠã€ããåŒã2ã€ã®éšåã«åå²ããŸãããã®æŒç®åã®åãšåŸã«ããããã®éšåã®æ§ç¯æäœãååž°çã«åŒã³åºããŸãã ã¢ã«ãŽãªãºã ã®æ®µéçãªèª¬æïŒ
ããã§ã¯ãåçŽãªçç±ã§ã¢ã«ãŽãªãºã ã®å®è£
ã説æããŸãã-ããã¯éåžžã«èšå€§ã§ãããèšäºã¯ããã«ã€ããŠã§ã¯ãããŸããã
ããªãŒã¯ããŒãã§æ§æãããåããŒãã¯TreeNodeæ§é ã§è¡šãããŸã
typedef struct TreeNode TreeNode ;
struct treeNode
{
TreeNodeTypeã¿ã€ã; //ããŒãã¿ã€ã
TreeNode *å·Š; //å·Šã®åã«ãªã³ã¯ããŸã
TreeNode * right ; //æ£ããåã®ãªã³ã¯
floatå€; //å€ïŒå®æ°ããŒãçšïŒ
} ;
èãããããã¹ãŠã®ã¿ã€ãã®ããŒãã¯æ¬¡ã®ãšããã§ãã
typedef åæå
{
OperatorPlus ã // Operator Plus
OperatorMinus ã //æŒç®åãã€ãã¹
OperatorMul ã //æŒç®åã®ä¹ç®
OperatorDiv ã //æŒç®ååå²
OperandConst ã //ãªãã©ã³ã-宿°
OperandVar ã //ãªãã©ã³ã-倿°
OperandNegVar ã //ãªãã©ã³ã-ãã€ãã¹ã§ãšããã倿°ïŒåé
ãã€ãã¹ã®åŠççšïŒ
} TreeNodeType ;
äžããããxã®åŒã®å€ã¯éåžžã«ç°¡åã«èšç®ãããŸã-æ·±ãã®ãŠã©ãŒã¯ã䜿çšããŠã
ãããååž°ã䜿çšããŠå®è£
ãããŸããfloat calcTreeFromRoot ïŒ TreeNode * root ã float x ïŒ
{
if ïŒ root- > type == OperandVar ïŒ
return x ;
if ïŒ root- > type == OperandNegVar ïŒ
return - x ;
if ïŒ root- > type == OperandConst ïŒ
ã«ãŒã->å€ãè¿ããŸãã
ã¹ã€ãã ïŒ root- > type ïŒ
{
ã±ãŒã¹ OperatorPlus ïŒ
return calcTreeFromRoot ïŒ root- > left ã x ïŒ + calcTreeFromRoot ïŒ root- > right ã x ïŒ ;
case OperatorMinus ïŒ
return calcTreeFromRoot ïŒã«ãŒã->å·Šã x ïŒ -calcTreeFromRoot ïŒã«ãŒã->å³ã x ïŒ ;
ã±ãŒã¹ OperatorMul ïŒ
return calcTreeFromRoot ïŒ root- > left ã x ïŒ * calcTreeFromRoot ïŒ root- > right ã x ïŒ ;
ã±ãŒã¹ OperatorDiv ïŒ
return calcTreeFromRoot ïŒ root- > left ã x ïŒ / calcTreeFromRoot ïŒ root- > right ã x ïŒ ;
}
}
çŸæç¹ã§ã¯äœã§ããïŒ
- åŒã®ããªãŒãçæãããŸã
- åŒã®å€ãèšç®ããå¿
èŠãããå Žåãååž°é¢æ°calcTreeFromRootãåŒã³åºãããŸã
ã¢ã»ã³ããªæ®µéã§åŒãç¥ã£ãŠããå Žåãã³ãŒãã¯ã©ã®ããã«ãªããŸããïŒ
float calcExpression ïŒ float x ïŒ
{
return x * x + 5 * x - 2 ;
}
ãã®å ŽåãåŒã®å€ã®èšç®ã¯ã1ã€ã®éåžžã«åçŽãªé¢æ°ã®åŒã³åºãã«åæžãããŸã-ååž°çãªããªãŒãã©ããŒãµã«ãããäœåãé«éã§ãã
ã³ã³ãã€ã«æéïŒ
IA32ã«é¡äŒŒããã¢ãŒããã¯ãã£ã®ããã»ããµã«åºã¥ããŠãx86ãã©ãããã©ãŒã çšã®ã³ãŒããçæããããšã«æ³šæããŠãã ããã ããã«ããããŒãã®ãµã€ãºã¯4ãã€ããintã®ãµã€ãºã¯4ãã€ãã§ãããšæ³å®ããŸããçè«
ãããã£ãŠãç§ãã¡ã®ã¿ã¹ã¯ã¯ãå¿
èŠã«å¿ããŠåŒã³åºãããšãã§ããCèšèªã®éåžžã®æ©èœãååŸããããšã§ãã
ãŸãããããã¿ã€ããå®çŸ©ããŸãããã
typedef float _cdecl ïŒ * Func ïŒ ïŒ float ïŒ ;
ããã§ãFuncããŒã¿åã¯ãfloatåã®å€ãè¿ã颿°ãžã®ãã€ã³ã¿ã«ãªããfloatåã®åŒæ°ã1ã€åãåããŸãã
_cdeclã¯ãC宣èšã®åŒã³åºãèŠçŽã䜿çšãããŠããããšã瀺ããŸãã
ããã¯ãCã®æšæºçãªåŒã³åºãèŠåã§ãã
-åŒæ°ã¯ãã¹ã¿ãã¯ãå³ããå·Šã«æž¡ãããŸãïŒã¹ã¿ãã¯ã®æäžéšã§åŒã³åºãããå Žåãæåã®åŒæ°ã¯æ¬¡ã®ããã«ãªããŸãïŒ
-æŽæ°å€ã¯EAXã¬ãžã¹ã¿ãä»ããŠè¿ãããŸã
-æµ®åå°æ°ç¹å€ã¯ã¬ãžã¹ã¿st0ãä»ããŠè¿ãããŸã
-
åŒã³åºã颿°ã¯ãã¬ãžã¹ã¿eaxãedxãecxã®å®å
šæ§ãæ
åœããŸãã
-æ®ãã®ã¬ãžã¹ã¿ã¯
ãåŒã³åºããã颿°
ã«ãã£ãŠåŸ©å
ããå¿
èŠããããŸã
颿°åŒã³åºãã¯æ¬¡ã®ããã«ãªããŸãã
push ebp //ã¹ã¿ãã¯ãã¬ãŒã ãã€ã³ã¿ãŒãä¿åããŸã
push arg3 //å³ããå·Šã®é ã«ã¹ã¿ãã¯ã«åŒæ°ãåŒããŸãïŒæåŸã®æåã®åŒæ°ïŒ
arg2ãããã·ã¥
arg1ãããã·ã¥
call func //åŒã³åºãèªäœ
add esp ã 0xC //ã¹ã¿ãã¯ãžã®ãã€ã³ã¿ã埩å
ããŸãïŒ4ãã€ãã®3ã€ã®åŒæ°ã¯0xCãã€ããå æããŸãïŒ
pop ebp //ã¹ã¿ãã¯ãã¬ãŒã ãã€ã³ã¿ãŒã埩å
ãã
åŒã³åºãæã®ã¹ã¿ãã¯ã®ç¶æ
ïŒ
åŒãè©äŸ¡ããã³ãŒããã©ã®ããã«çæããŸããïŒ ã¹ã¿ãã¯èšç®æ©ã®ãããªãã®ãããããšãæãåºããŠãã ããã 圌ã¯ã©ã®ããã«åããŠããŸããïŒ å
¥åçªå·ãšæŒç®åã ä»äºã®ã¢ã«ãŽãªãºã ã¯åºæ¬çã§ãïŒ
-宿°ãŸãã¯å€æ°ãæºãããŸãã-ã¹ã¿ãã¯ã«é
眮ããŸã
-æŒç®åã«é©å-ã¹ã¿ãã¯2ãªãã©ã³ãããåé€ãæäœãå®è¡ãçµæãã¹ã¿ãã¯ã«é
眮
ãã ããç¹å®ã®æ¹æ³ã§ã¹ã¿ãã¯èšç®æ©ã«å
¥åããå¿
èŠããããŸããããã¯ãéããŒã©ã³ãèšæ³ã§æç€ºãããåŒã§æ©èœããŸãã ãã®ç¹ç°æ§ã¯ããªãã©ã³ããæåã«ã¬ã³ãŒãã«ãããæ¬¡ã«æŒç®åã«ãããšããäºå®ã«ãããŸãã ãããã£ãŠãå
ã®åŒã¯æ¬¡ã®ããã«ãªããŸãã
åŒã«å¯Ÿå¿ããã¹ã¿ãã¯èšç®æ©ã®ããã°ã©ã ïŒ
xãæŒã
xãæŒã
ãã«
ããã·ã¥ 5
xãæŒã
ãã«
å ãã
ããã·ã¥ 2
ãµã
ã¢ã»ã³ãã©ãŒããã°ã©ã ã«éåžžã«äŒŒãŠããŸããïŒ
åŒãéããŒã©ã³ã衚èšã«å€æããåºæ¬èŠåã«åŸã£ãŠã³ãŒããäœæããã°ååã§ããããšãããããŸãã
倿ã¯éåžžã«ç°¡åã§ã-è§£æããªãŒããã§ã«æ§ç¯ãããŠããã®ã§ãæ·±ãã調ã¹ãã ãã§ãé ç¹ãåºããšãã«å¯Ÿå¿ããã¢ã¯ã·ã§ã³ãçæããŸã-å¿
èŠãªé åºã§ã³ãã³ãã®ã·ãŒã±ã³ã¹ãååŸããŸãã
ãã®ã¢ã¯ã·ã§ã³ã®æ¬äŒŒã³ãŒãïŒstatic void generateCodeR ïŒ TreeNode * root ã ByteArray * code ïŒ
{
if ïŒ root- > left ïŒamp ;ïŒamp ; root- > right ïŒ
{
generateCodeR ïŒã«ãŒã->å³ãã³ãŒãïŒ ; //æåã«çæããå¿
èŠããããŸã
generateCodeR ïŒã«ãŒã->å·Šãã³ãŒãïŒ ; //åèŠçŽ ã®èšç®ã³ãŒã
}
//芪èŠçŽ ã®ã³ãŒããçæããŸã
if ïŒ root- > type == OperandVar ïŒ
{
ã³ãŒã+ = "ããã·ã¥x" ; //åŒæ°ïŒå€æ°ïŒã®å€ãã¹ã¿ãã¯ã«é
眮ããŸã
}
else if ïŒ root- > type == OperandNegVar ïŒ
{
ã³ãŒã+ = "push -x" ; //笊å·ã倿ŽããŠåŒæ°ã®å€ãã¹ã¿ãã¯ã«é
眮ããŸã
}
else if ïŒ root- > type == OperandConst ïŒ
{
code + = "push" + root- > value ; //宿°ãã¹ã¿ãã¯ã«é
眮ããŸã
}
ä»ã«
{
ã³ãŒã+ = "ããã" ; //ã¹ã¿ãã¯ããåé€
ã³ãŒã+ = "ããã" ; // 2ã€ã®å€
ã¹ã€ãã ïŒ root- > type ïŒ
{
ã±ãŒã¹ OperatorPlus ïŒ
ã³ãŒã+ = "远å " ; //远å ãå®è¡ããŸã
äŒæ© ;
case OperatorMinus ïŒ
ã³ãŒã+ = "sub" ; //æžç®
äŒæ© ;
ã±ãŒã¹ OperatorMul ïŒ
ã³ãŒã+ = "mul" ; //ä¹ç®ãå®è¡ããŸã
äŒæ© ;
ã±ãŒã¹ OperatorDiv ïŒ
ã³ãŒã+ = "div" ; //åå²ãè¡ããŸã
äŒæ© ;
}
code + = "push result" //ç®è¡æŒç®ã®çµæãã¹ã¿ãã¯ã«ä¿åããŸã
}
}
å®è£
ãŸããã¹ã¿ãã¯ã決å®ããŸãããããã¹ãŠãã·ã³ãã«ã§ã-espã¬ãžã¹ã¿ã«ã¯æäžéšãžã®ãã€ã³ã¿ãå«ãŸããŠããŸãã ããã«äœãã眮ãã«ã¯ãã³ãã³ããå®è¡ããã ãã§ã
ããã·ã¥ {å€}
ãŸãã¯ãESPããæ°å€4ãæžç®ããåä¿¡ããã¢ãã¬ã¹ã«ç®çã®å€ãæžã蟌ã¿ãŸã
sub esp ã 4
mov [ esp ] ã {å€}
ã¹ã¿ãã¯ããåé€ããã«ã¯ãpopã³ãã³ããŸãã¯espã«4ã远å ããŸãã
以åã¯åŒã³åºãèŠçŽã«ã€ããŠèšåããŠããŸããã ãã®ãããã§ã颿°ã®åäžã®åŒæ°ãã©ãã«ãªãããæ£ç¢ºã«ç¥ãããšãã§ããŸãã espã¢ãã¬ã¹ïŒå
é ïŒã«ã¯æ»ãã¢ãã¬ã¹ãå«ãŸããesp-4ã¢ãã¬ã¹ã«ã¯åŒæ°ã®å€ã®ã¿ãå«ãŸããŸãã æ¯èŒçé »ç¹ã«ã¢ã¯ã»ã¹ããããããeaxã¬ãžã¹ã¿ã«é
眮ã§ããŸãã
mov eax ã [ esp - 4 ] ;
次ã«ãæµ®åå°æ°ç¹æ°ã®æäœã«ã€ããŠå°ã説æããŸãã x87 FPUåœä»€ã»ããã䜿çšããŸãã
FPUã«ã¯ãã¹ã¿ãã¯ã圢æãã8ã€ã®ã¬ãžã¹ã¿ããããŸãã ããããã80ããããä¿æããŸãã ãã®ã¹ã¿ãã¯ã®æäžéšã«ã¯ãã¬ãžã¹ã¿st0ãä»ããŠã¢ã¯ã»ã¹ããŸãã ãããã£ãŠãã¬ãžã¹ã¿st1ã¯ããã®ã¹ã¿ãã¯å
ã®ãã®é ç¹ã«ç¶ãå€ãst2-次ã®å€ããªã©ãst7ã«ã¢ãã¬ã¹æå®ããŸãã
FPUã¹ã¿ãã¯ïŒ
å€ãäžçªäžã«ããŒãããã«ã¯ãfldã³ãã³ãã䜿çšããŸãã ãã®ã³ãã³ãã®ãªãã©ã³ãã¯ãã¡ã¢ãªã«ä¿åãããå€ã®ã¿ã§ãã
fld [ esp ] // espã«å«ãŸããã¢ãã¬ã¹ã«æ ŒçŽãããŠããå€ãst0ã«ããŒãããŸã
ç®è¡æŒç®ãå®è¡ããã³ãã³ãã¯éåžžã«ç°¡åã§ãïŒfaddãfsubãfmulãfdivã åŒæ°ã«ã¯ããŸããŸãªçµã¿åããããããŸãããæ¬¡ã®ããã«ã®ã¿äœ¿çšããŸãã
fadd dword ptr [ esp ]
fsub dword ptr [ esp ]
fmul dword ptr [ esp ]
fdiv dword ptr [ esp ]
ããããã¹ãŠã®å Žåã[esp]ããã®å€ãããŒããããå¿
èŠãªæäœãå®è¡ãããçµæãst0ã«æ ŒçŽãããŸãã
ã¹ã¿ãã¯ããå€ãåé€ããã®ãç°¡åã§ãã
fstp [ esp ] // FPUã¹ã¿ãã¯ã®æäžéšããå€ãåé€ããespã®ã¢ãã¬ã¹ã®ã¡ã¢ãªäœçœ®ã«ä¿åããŸã
åŒã§ã¯ãåé
ãã€ãã¹ãæã€x倿°ãçºçããå¯èœæ§ãããããšãæãåºããŠãã ããã ãããåŠçããã«ã¯ãèšå·ã倿Žããå¿
èŠããããŸãã FCHSã³ãã³ãã¯ãã®ã²ãŒã ã«åœ¹ç«ã¡ãŸã-ã¬ãžã¹ã¿ç¬Šå·st0ã®ããããå転ããŸã
ãããã®åã³ãã³ãã«ã€ããŠãå¿
èŠãªãªãã³ãŒããçæãã颿°ã«ãã£ãŠæ±ºå®ããŸãã
void genPUSH_imm32 ïŒ ByteArray * code ã int32_t * pValue ïŒ ;
void genADD_ESP_4 ïŒ ByteArray * code ïŒ ;
void genMOV_EAX_PTR_ESP_4 ïŒ ByteArray * code ïŒ ;
void genFSTP ïŒ ByteArray * code ã void * dstAddress ïŒ ;
void genFLD_DWORD_PTR_ESP ïŒ ByteArray * code ïŒ ;
void genFADD_DWORD_PTR_ESP ïŒ ByteArray * code ïŒ ;
void genFSUB_DWORD_PTR_ESP ïŒ ByteArray * code ïŒ ;
void genFMUL_DWORD_PTR_ESP ïŒ ByteArray * code ïŒ ;
void genFCHS ïŒ ByteArray * code ïŒ ;
èšç®æ©ã³ãŒããæ£åžžã«æ©èœããå€ãè¿ãããã«ã¯ããã®ååŸã«é©åãªæç€ºã远å ããå¿
èŠããããŸãã å
šäœã¯generateCodeã©ãããŒé¢æ°ã«ãã£ãŠãŸãšããããŸãïŒ
void generateCode ïŒ Tree * tree ã ByteArray * resultCode ïŒ
{
ByteArray * code = resultCode ;
genMOV_EAX_ESP_4 ïŒã³ãŒãïŒ ; //åŒæ°ã®å€ãeaxã«å
¥ããŸã
generateCodeR ïŒããªãŒ->ã«ãŒããã³ãŒãïŒ ; //èšç®æ©ã³ãŒããçæããŸã
genFLD_DWORD_PTR_ESP ïŒã³ãŒãïŒ ;
genADD_ESP_4 ïŒã³ãŒãïŒ ; //ã¹ã¿ãã¯ããäœåãªããã«ã¯ãŒããåé€ããŸã
genRET ïŒã³ãŒãïŒ ; //颿°ãçµäºããŸã
}
åŒã®å€ãèšç®ããã³ãŒãçæé¢æ°ã®æçµåœ¢åŒïŒvoid generateCodeR ïŒ TreeNode * root ã ByteArray * resultCode ïŒ
{
ByteArray * code = resultCode ;
if ïŒ root- > left ïŒamp ;ïŒamp ; root- > right ïŒ
{
generateCodeR ïŒã«ãŒã->å³ãã³ãŒãïŒ ;
generateCodeR ïŒã«ãŒã->å·Šãã³ãŒãïŒ ;
}
if ïŒ root- > type == OperandVar ïŒ
{
genPUSH_EAX ïŒã³ãŒãïŒ ; //颿°ã®åŒæ°ã¯eaxã«ãããŸã
}
else if ïŒ root- > type == OperandNegVar ïŒ
{
genPUSH_EAX ïŒã³ãŒãïŒ ; //ã¹ã¿ãã¯ã«ããŒãããŸã
genFLD_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //倿Ž
genFCHS ïŒã³ãŒãïŒ ; //ãµã€ã³
genFSTP_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //ã¹ã¿ãã¯ã«æ»ã
}
else if ïŒ root- > type == OperandConst ïŒ
{
genPUSH_imm32 ïŒ code ã ïŒ int32_t * ïŒ ïŒamp ; root- > value ïŒ ;
}
ä»ã«
{
genFLD_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //å·Šã®ãªãã©ã³ããFPUã«ããŒãããŸã..
genADD_ESP_4 ïŒã³ãŒãïŒ ; // ...ãããŠã¹ã¿ãã¯ããåé€ããŸã
ã¹ã€ãã ïŒ root- > type ïŒ
{
ã±ãŒã¹ OperatorPlus ïŒ
genFADD_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //å ç®ãå®è¡ããŸãïŒçµæã¯st0ã«ä¿åãããŸãïŒ
äŒæ© ;
case OperatorMinus ïŒ
genFSUB_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //æžç®ïŒçµæã¯st0ã«ä¿åãããŸãïŒ
äŒæ© ;
ã±ãŒã¹ OperatorMul ïŒ
genFMUL_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //ä¹ç®ãå®è¡ããŸãïŒçµæã¯st0ã«ä¿åãããŸãïŒ
äŒæ© ;
ã±ãŒã¹ OperatorDiv ïŒ
genFDIV_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //é€ç®ãè¡ããŸãïŒçµæã¯st0ã«ä¿åãããŸãïŒ
äŒæ© ;
}
genFSTP_DWORD_PTR_ESP ïŒã³ãŒãïŒ ; //çµæãã¹ã¿ãã¯ã«ä¿åããŸãïŒst0-ïŒgt; [esp]ïŒ
}
}
ã³ãŒããä¿åããããã®ãããã¡ãšããã°ã ãããã®ç®çã®ããã«ãByteArrayã³ã³ãããŒã¿ã€ããäœæããŸããã
typedef æ§é äœ
{
intãµã€ãº; //å²ãåœãŠãããã¡ã¢ãªã®ãµã€ãº
int dataSize ; //ä¿åãããããŒã¿ã®å®éã®ãµã€ãº
char * data ; //ããŒã¿ãžã®ãã€ã³ã¿ãŒ
} ByteArray ;
ByteArray * byteArrayCreate ïŒ int initialSize ïŒ ;
void byteArrayFree ïŒ ByteArray * array ïŒ ;
void byteArrayAppendData ïŒ ByteArray * array ã const char * data ã int dataSize ïŒ ;
ããŒã¿ãæåŸã«è¿œå ããããšãã§ããã¡ã¢ãªã®å²ãåœãŠã«ã€ããŠèããå¿
èŠã¯ãããŸãã-åçé
åã®äžçš®ã§ãã
generateCodeïŒïŒã䜿çšããŠã³ãŒããçæããããã«å¶åŸ¡ãæž¡ããšãã»ãšãã©ã®å Žåãããã°ã©ã ãã¯ã©ãã·ã¥ããŸãã çç±ã¯åçŽã§ã-å®è¡ããæš©éããããŸããã ç§ã¯Windowsã§æžããŠããã®ã§ãWinAPI VirtualProtect颿°ã¯ããã§åœ¹ç«ã¡ãŸããããã«ãããã¡ã¢ãªé åïŒãŸãã¯ã¡ã¢ãªããŒãžïŒã®ã¢ã¯ã»ã¹èš±å¯ãèšå®ã§ããŸãã
MSDã§ã¯ã次ã®ããã«èšè¿°ãããŸãã
BOOL WINAPI VirtualProtect ïŒ
_In_ LPVOID lpAddress ã //ã¡ã¢ãªå
ã®é åã®å
é ã®ã¢ãã¬ã¹
_In_ SIZE_T dwSize ã //ã¡ã¢ãªå
ã®é åã®ãµã€ãº
_In_ DWORD flNewProtect ã //ãªãŒãžã§ã³å
ã®ããŒãžã®æ°ããã¢ã¯ã»ã¹èšå®
_Out_ PDWORD lpflOldProtect //å€ãã¢ã¯ã»ã¹ãã©ã¡ãŒã¿ãä¿åãã倿°ãžã®ãã€ã³ã¿
ïŒ ;
ã¡ã€ã³ã³ã³ãã€ã©é¢æ°ã§äœ¿çšãããŸãã
CompiledFunc compileTree ïŒããªãŒ*ããªãŒïŒ
{
CompiledFuncçµæ;
DWORD oldP ;
ByteArray *ã³ãŒã;
code = byteArrayCreate ïŒ 2 ïŒ ; //ã³ã³ããã®åæãµã€ãºã¯2ãã€ãã§ã
generateCode ïŒããªãŒãã³ãŒãïŒ ; //ã³ãŒããçæããŸã
VirtualProtect ïŒã³ãŒã->ããŒã¿ãã³ãŒã-> dataSize ã PAGE_EXECUTE_READWRITE ã ããã³ oldP ïŒ ; //å®è¡æš©ãä»äžããŸã
çµæã code = code ;
çµæã run = ïŒ Func ïŒçµæã ã³ãŒã ->ããŒã¿;
çµæãè¿ã ;
}
CompiledFunc-ã³ãŒããšé¢æ°ãžã®ãã€ã³ã¿ãŒã䟿å©ã«ä¿åããããã®æ§é ïŒ
typedef æ§é äœ
{
ByteArray *ã³ãŒã; //ã³ãŒãä»ãã³ã³ãã
Func run ; //颿°ãã€ã³ã¿
} CompiledFunc ;
ã³ã³ãã€ã©ã¯æžãããŠããããã®äœ¿çšã¯éåžžã«ç°¡åã§ãã
ããªãŒ*ããªãŒ;
CompiledFunc f ;
ãããŒãçµæ;
tree = buildTreeForExpression ïŒ "x + 5" ïŒ ;
f = compileTree ïŒããªãŒïŒ ;
çµæ= fã å®è¡ ïŒ 5 ïŒ ; //çµæ= 10
é床ã®ãã¹ãã宿œããã ãã§ãã
ãã¹ãäž
ãã¹ãäžã«ãã³ã³ãã€ã«ãããã³ãŒãã®ã©ã³ã¿ã€ã ãšãååž°çãªããªãŒããŒã¹ã®èšç®ã¢ã«ãŽãªãºã ãæ¯èŒããŸãã æšæºã©ã€ãã©ãªã®clockïŒïŒé¢æ°ã䜿çšããŠæéãæž¬å®ããŸãã ã³ãŒãã»ã¯ã·ã§ã³ã®äœæ¥æéãèšç®ããã«ã¯ããããã¡ã€ã«ãããéšåã®ååŸã«åŒã³åºãã®çµæãä¿åããã ãã§ååã§ãã ãããã®å€ã®å·®ã宿°CLOCKS_PER_SECã§é€ç®ãããšãã³ãŒãã©ã³ã¿ã€ã ãæ°ç§ã§ååŸã§ããŸãã ãã¡ãããããã¯éåžžã«æ£ç¢ºãªæž¬å®æ¹æ³ã§ã¯ãããŸããããããæ£ç¢ºã«ããå¿
èŠã¯ãããŸããã§ããã
ãšã©ãŒã®åŒ·ã圱é¿ãé¿ããããã«ã颿°ã®ç¹°ãè¿ãåŒã³åºãã®æéãæž¬å®ããŸãã
ãã¹ãçšã®ã³ãŒãïŒ
double measureTimeJIT ïŒ Tree * tree ã æŽæ° ïŒ
{
int i ;
äºéçµæ;
clock_t start ã end ;
CompiledFunc f ;
start = clock ïŒ ïŒ ;
f = compileTree ïŒããªãŒïŒ ;
for ïŒ i = 0 ; i ïŒ lt ; iters ; i ++ ïŒ
{
fã run ïŒ ïŒ float ïŒ ïŒ i ïŒ
1000 ïŒ ïŒïŒ ;
}
end = clock ïŒ ïŒ ;
result = ïŒ end - start ïŒ / ïŒ double ïŒ CLOCKS_PER_SEC ;
compileFuncFree ïŒ f ïŒ ;
çµæãè¿ã ;
}
double measureTimeNormal ïŒ Tree * tree ã æŽæ° ïŒ
{
int i ;
clock_t start ã end ;
äºéçµæ;
start = clock ïŒ ïŒ ;
for ïŒ i = 0 ; i ïŒ lt ; iters ; i ++ ïŒ
{
calcTree ïŒ tree ã ïŒ float ïŒ ïŒ i ïŒ
1000 ïŒ ïŒ ;
}
end = clock ïŒ ïŒ ;
result = ïŒ end - start ïŒ / ïŒ double ïŒ CLOCKS_PER_SEC ;
çµæãè¿ã ;
}
ãã¹ã¿ãŒèªäœã®ã³ãŒãã¯ããªããžããªã§è¡šç€ºã§ããŸãã 圌ã¯ã調æŽå¯èœãªå¶éå
ã§å
¥åããŒã¿ã®ãµã€ãºãé£ç¶çã«å¢ãããäžèšã®ãã¹ã颿°ãåŒã³åºããçµæããã¡ã€ã«ã«æžã蟌ãã ãã§ãã
ãããã®ããŒã¿ã«åºã¥ããŠãå
¥åããŒã¿ã®ãµã€ãºïŒåŒã®é·ãïŒã«å¯ŸããŠã©ã³ã¿ã€ã ãããããããŸããã æž¬å®ã®ååŸ©åæ°ãšããŠ100äžãæ¡çšããŸããã ãã®ããã«ã ã¹ããªã³ã°ã®é·ãã¯ã0ãã2000ãŸã§é 次å¢å ããŸããã

éãã°ã©ãã¯ãã³ã³ãã€ã«ãããã³ãŒãã®å®è¡æéã®ã¿ã¹ã¯ã®ãµã€ãºãžã®äŸåæ§ã§ãã
èµ€ãã°ã©ãã¯ãã¿ã¹ã¯ã®ãµã€ãºã«å¯Ÿããååž°ã¢ã«ãŽãªãºã ã®å®è¡æéã®äŸåæ§ã§ãã
é»ãã°ã©ãã¯ã1çªç®ãš2çªç®ã®ã°ã©ãã®å¯Ÿå¿ãããã€ã³ãã®y座æšã§ãã ã¿ã¹ã¯ã®ãµã€ãºã«å¿ããŠJITãé«éåãããåæ°ã瀺ããŸãã
å
¥åããŒã¿ãµã€ãº= 2000ã®å ŽåãJITãçŽ9.4ååã€ããšãããããŸãã ããã¯ããªãè¯ããšæããŸãã
JITã®æ¹ãéãã®ã¯ãªãã§ããïŒ
ã³ã³ãã€ã«ãããã³ãŒãã¯å®å
šã«ç·åœ¢ã§ãããåäžã®æ¡ä»¶ä»ããžã£ã³ãã§ã¯ãããŸããã ãã®ãããå®è¡äžã«ããã»ããµãã€ãã©ã€ã³ã®åäžã®ãªã»ãããçºçããããšã¯ãããŸãããããã¯ããã©ãŒãã³ã¹ã«ãšã£ãŠéåžžã«æçã§ãã
ããè¯ãæ¹æ³ã¯ãããŸããïŒ
ã³ã³ãã€ã©ã®æå€§ã®åé¡ã¯ãFPUã®ãã¹ãŠã®æ©èœã䜿çšããªãããšã§ãã FPU 8ã¬ãžã¹ã¿ã§ã¯ã匷å¶çã«2ã€äœ¿çšããŸãã ã¹ã¿ãã¯ã®äžéšãFPUã¹ã¿ãã¯ã«è»¢éã§ããå Žåãèšç®é床ã倧å¹
ã«åäžããã¯ãã§ãïŒããã«ãããã¯ãã¹ãããå¿
èŠããããŸãïŒã
å¥ã®æ¬ ç¹ã¯ãã³ã³ãã€ã©ãéåžžã«æãã§ããããšã§ãã 圌ã¯å®æ°åŒãèšç®ãããäžå¿
èŠãªèšç®ãé¿ããŸããã æå€§éã®ãªãœãŒã¹ãæ¶è²»ããããã«åŒãäœæããã®ã¯éåžžã«ç°¡åã§ãã åŒã®åºæ¬çãªåçŽåã远å ãããšãã³ã³ãã€ã©ã¯çæ³ã«è¿ã¥ããŸãã
å®è£
èªäœã®åé¡ã¯ãå¥ã®ãã©ãããã©ãŒã ïŒã³ãŒãçææ©èœã§ç¹å®ã®ã³ãã³ãã䜿çšãããïŒããã³ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ïŒããã§ãVirtualProtectïŒãžã®åçŽãªç§»æ€ã®äžå¯èœæ§ãšèããããšãã§ããŸãã å®å
šã«æçœã§ããªãåçŽãªãœãªã¥ãŒã·ã§ã³ã¯ããã©ãããã©ãŒã åºæã®éšåãšOSåºæã®éšåãæœè±¡åãããããã®å®è£
ãåå¥ã®ã¢ãžã¥ãŒã«ã«é
眮ããããšã§ãã
èªãã§ãããŠããããšããã³ã¡ã³ããšãã³ããæ¬åœã«æ¥œãã¿ã«ããŠããŸãããªããžããªïŒ
bitbucket.org/Informhunter/jithabrãã®èšäºã¯ããPerfect Codeããšããæ¬ãã€ãŸããç»ååŠçã®ããã®ã³ãŒãã®åççæããšããç« ã«è§ŠçºãããŸããã