2010年9月8日 星期三

disassemble your code @ objdump ....

除了用 gcc -S 來產生 *.s 的 assembly code之外. 也可以用 objdump + strace 的 command 來做 assemble && system call trace. sample code @ c
TT *get_TTNode(TT *p,int Id){
    TT *tPtr = p;

    while(tPtr!=NULL){
      if( tPtr->Id == Id ){
           return tPtr; break;
      }
      tPtr = tPtr->Nxt;
   }

return NULL;
}
objdump -d (disassemble)
080484d3 <get_TTNode>:
 80484d3:       55                      push   %ebp
 80484d4:       89 e5                   mov    %esp,%ebp                        // store current stack pointer
 80484d6:       83 ec 14                sub    $0x14,%esp
 80484d9:       8b 45 08                mov    0x8(%ebp),%eax                   // get "TT *p"
 80484dc:       89 45 fc                mov    %eax,-0x4(%ebp)                  // "TT *tPtr = p"
 80484df:       eb 1b                   jmp    80484fc <get_TTNode+0x29>  // jump to while loop 
 80484e1:       8b 45 fc                mov    -0x4(%ebp),%eax                  // "tPtr->Id"
 80484e4:       8b 00                   mov    (%eax),%eax                      // mov to eax register
 80484e6:       3b 45 0c                cmp    0xc(%ebp),%eax                   // cmp (tPtr->Id == Id )? true : false;
 80484e9:       75 08                   jne    80484f3 <get_TTNode+0x20>
 80484eb:       8b 45 fc                mov    -0x4(%ebp),%eax                  
 80484ee:       89 45 ec                mov    %eax,-0x14(%ebp)                 // return tPtr
 80484f1:       eb 16                   jmp    8048509 <get_TTNode+0x36>  // break
 80484f3:       8b 45 fc                mov    -0x4(%ebp),%eax
 80484f6:       8b 40 0c                mov    0xc(%eax),%eax                   // tPtr = tPtr->Nxt
 80484f9:       89 45 fc                mov    %eax,-0x4(%ebp)
 80484fc:       83 7d fc 00             cmpl   $0x0,-0x4(%ebp)                  // while loop
 8048500:       75 df                   jne    80484e1 <get_TTNode+0xe>           // cmp (tPtr!=NULL)? true : false;
 8048502:       c7 45 ec 00 00 00 00    movl   $0x0,-0x14(%ebp)
 8048509:       8b 45 ec                mov    -0x14(%ebp),%eax                 //return NULL
 804850c:       c9                      leave  
 804850d:       c3                      ret 
Refs : objdump strace

2010年9月7日 星期二

LEX && YACC sample case pt2

接續 LEX && YACC sample case pt1 幫 List-Node 穿上 Lex && Yacc 的衣服....^_^.再依序填入List中. sample.l
%{
#include "y.tab.h"
%}

%%
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
  yylval.dval = atof(yytext);
  return NUMBER;
 }

[ \t] ;   /* ignore white space */

[A-Za-z][A-Za-z0-9]* { /* return symbol pointer */
  return NAME;
 }

"$" { return 0; }

\n |
. return yytext[0];
%%
int yywrap()
{
    return 1;
}
sample.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "tt.h"
int OpId =0;
struct LIST   *lstr; 
%}

%union {
 double dval;
}
%token <dval> NAME
%token <dval> NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%type <dval> expression
%%
statement_list: statement '\n'
 | statement_list statement '\n'
 ;

statement: NAME '=' expression { $1 = $3; }
 | expression  { printf("= %g\n", $1);
  displayOp();
  OpId =0; 
  lstr =NULL;
 }
 ;

expression: expression '+' expression { $$ = $1 + $3; 
    LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_ADD,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
  }
 | expression '-' expression { $$ = $1 - $3; 
    LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_SUB,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
  }
 | expression '*' expression { $$ = $1 * $3;
     LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_MUL,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
  }
 | expression '/' expression
    { if($3 == 0.0)
      yyerror("divide by zero");
     else{
      $$ = $1 / $3;
     LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_DIV,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
     }
    }
 | '-' expression %prec UMINUS { $$ = -$2; }
 | '(' expression ')' { $$ = $2; }
 | NUMBER
 | NAME   { $$ = $1; }
 ;
%%

int displayOp(){
LIST *tlstr = (void *)lstr;
TT   *tPtr = NULL; //TT   point
LIST *lPtr = NULL; //LIST point

int i=0;
char* Opst;
for(i=0; i<OpId; i++){

 if(tlstr == NULL ){ printf("<E1> Initial List Error ...\n"); return -1; }
 lPtr = get_List(tlstr,i);

 switch(lPtr->Typ){
   case TT_ADD : printf("Op(%d) -> ADD\n",i);  break;
   case TT_SUB : printf("Op(%d) -> SUB\n",i);  break;
   case TT_MUL : printf("Op(%d) -> MUL\n",i);  break;
   case TT_DIV : printf("Op(%d) -> DIV\n",i);  break;
   case TT_MOD : printf("Op(%d) -> MOD\n",i);  break;
 default: return -1; break;
        }

 printf("SRC1...\n");
 if(lPtr == NULL ){ printf("<E2> Get Ptr Error ...\n"); return -1; }
 tPtr = (void *)lPtr->Parent;
 if(tPtr == NULL ){ printf("<E3> Get Ptr->Parent Error ...\n"); return -1; }
 tPtr = get_TTNode(tPtr,TT_SRC1);
 if(tPtr == NULL ){ printf("<E4> Get Ptr->Parent->Src1 Error ...\n"); return -1; }
 display_TTNode(tPtr);

 printf("SRC2...\n");
 if(lPtr == NULL ){ printf("<E2> Get Ptr Error ...\n"); return -1; }
 tPtr = (void *)lPtr->Parent;
 if(tPtr == NULL ){ printf("<E3> Get Ptr->Parent Error ...\n"); return -1; }
 tPtr = get_TTNode(tPtr,TT_SRC2);
 if(tPtr == NULL ){ printf("<E4> Get Ptr->Parent->Src2 Error ...\n"); return -1; }
 display_TTNode(tPtr);

 printf("DST...\n");
 if(lPtr == NULL ){ printf("<E2> Get Ptr Error ...\n"); return -1; }
 tPtr = (void *)lPtr->Child;
 if(tPtr == NULL ){ printf("<E3> Get Ptr->Child Error ...\n"); return -1; }
 tPtr = get_TTNode(tPtr,TT_DST);
 if(tPtr == NULL ){ printf("<E4> Get Ptr->Child->DST Error ...\n"); return -1; }
 display_TTNode(tPtr);
 }

 printf("=====================\n");
 printf("\n");
 printf("\n");
}


int yyerror(char const *str)
{
    extern char *yytext;
    fprintf(stderr, "parser error near %s\n", yytext);
    return 0;
}

int main(void)
{
    extern int yyparse(void);
    extern FILE *yyin;

    yyin = stdin;
    if (yyparse()) {
        fprintf(stderr, "Error ! Error ! Error !\n");
        exit(1);
    }
}

Results: (1+2)*2 = 6 Op(0) -> ADD SRC1... Id :: 5,Nm :: 1.000000 SRC2... Id :: 6,Nm :: 2.000000 DST... Id :: 7,Nm :: 3.000000 Op(1) -> MUL SRC1... Id :: 5,Nm :: 3.000000 SRC2... Id :: 6,Nm :: 2.000000 DST... Id :: 7,Nm :: 6.000000 ===================== 1+2*2 = 5 Op(0) -> MUL SRC1... Id :: 5,Nm :: 2.000000 SRC2... Id :: 6,Nm :: 2.000000 DST... Id :: 7,Nm :: 4.000000 Op(1) -> ADD SRC1... Id :: 5,Nm :: 1.000000 SRC2... Id :: 6,Nm :: 4.000000 DST... Id :: 7,Nm :: 5.000000 ===================== project download here Refs lex&yacc 第一章例5 lex & yacc, 2nd Edition lex_and_yacc_chinese_version