#include "../std.h" #include "../ex.h" #include "operand.h" #include "insts.h" static const char *regs[]={ "al","cl","dl","bl","ah","ch","dh","bh", "ax","cx","dx","bx","sp","bp","si","di", "eax","ecx","edx","ebx","esp","ebp","esi","edi" }; static void opError(){ throw Ex( "error in operand" ); } static void sizeError(){ throw Ex( "illegal operand size" ); } Operand::Operand() :mode(NONE),reg(-1),imm(0),offset(0),baseReg(-1),indexReg(-1),shift(0){ } Operand::Operand( const string &s ) :mode(NONE),reg(-1),imm(0),offset(0),baseReg(-1),indexReg(-1),shift(0),s(s){ } bool Operand::parseSize( int *sz ){ if( !s.size() ) return false; if( s.find( "byte " )==0 ){ *sz=1;s=s.substr( 5 ); }else if( s.find( "word " )==0 ){ *sz=2;s=s.substr( 5 ); }else if( s.find( "dword " )==0 ){ *sz=4;s=s.substr( 6 ); }else return false; return true; } bool Operand::parseChar( char c ){ if( !s.size() || s[0]!=c ) return false; s=s.substr( 1 );return true; } bool Operand::parseReg( int *reg ){ int i; for( i=0;i'7' ) return false; *reg=s[3]-'0';s=s.substr( 5 );return true; } bool Operand::parseLabel( string *label ){ if( !s.size() || (!isalpha( s[0] ) && s[0]!='_') ) return false; int i; for( i=1;i=0 ) break; if( parseChar( '1' ) ) shift=0; else if( parseChar( '2' ) ) shift=1; else if( parseChar( '4' ) ) shift=2; else if( parseChar( '8' ) ) shift=3; else break; indexReg=n; }else{ if( baseReg<0 ) baseReg=n; else if( indexReg<0 ){ indexReg=n; } else break; } }else if( parseLabel( &l ) ){ if( baseLabel.size() ) opError(); baseLabel=l; }else if( parseConst( &n ) ){ offset+=n; }else break; if( !s.size() ) return; } opError(); }