Re: A sample RosAsm macro (actually a whole set)

From: RoWsRaIrTiEo (non_at_esist.eeee)
Date: 02/13/04


Date: Fri, 13 Feb 2004 08:26:39 GMT

On Mon, 09 Feb 2004 16:23:19 +0000, Woody
<m.woodmass@nobloodyspam.ntlworld.com> wrote:

>On Mon, 9 Feb 2004 08:50:03 +0100, "The Half A Wannabee"
><ShakainZulu_AT(Nightwish - She Is My Sin (Live).mp3)_Hotmail.com>
>wrote:
>
>> Heres my LET eax = ebx + 4
>>
>>mov eax ebx | add eax 4
>
>lea eax, [ebx+4]

If I make some change
install( "%1 = %2 + %3", "mov %1, %2 \n add %1, %3 ");
install( "%1 = %2 - %3", "mov %1, %2 \n sub %1, %3 ");
seams to work if for me numbers are [+/-0123456789]

so ax = cx -34 ax=cx +34 are not ok
ax=cx- 34 \\ ax=bx+cx \\ ax = bx - 34 are ok
cx=ax+ -78\\ cx=ax+ +67 are ok too
bx =34+ax \\ cx= 45+88 \\ ax = -67+ax \\ cx=-67+45 \\cx=-34+ax
are ok too

Macro in C are dangerous because they are free to make disasters
without any *warning* from the compiler;
and because is difficult *to see* how a macro is expanded in a file;

/* NOME DEL FILE 2.c */
/* questo programma ha un diverso tipo di getword
 serve come preprocessore di macro per file .asm */

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define R return
#define P printf
#define F for
#define W while
#define UC unsigned char
#define MAXW 500
#define HASHSIZE 101

struct nlist{
 struct nlist* next;
 char* name;
 char* defn;
};

static struct nlist* hashtab[HASHSIZE];

/*hash: calcola il valore di hashing della stringa s*/
unsigned hash(char* s)
{unsigned hashval;
 if(s==NULL) R 0;
 F(hashval=0;*s!='\0';++s)
     hashval=*s+31*hashval;
 R hashval%HASHSIZE;
}

/*lookup: cerca s in hashtab*/
struct nlist* lookup(char* s)
{struct nlist *np;
 if(s==NULL) R NULL;
 F(np=hashtab[hash(s)];np!=NULL;np=np->next)
   if(strcmp(s,np->name)==0)
                  R np; /* trovata */
 R NULL; /*non trovata*/
}

/* dupstr: fa una copia di s */
char* dupstr(char* s)
{char *p;
 if(s==NULL) return NULL;
 p=malloc(strlen(s)+1); /* +1 per '\0' */
 if(p!=NULL)
    strcpy( p, s );
 return p;
}

void free_node(struct nlist* a)
{if(a==NULL) R;
 if(a->name!=NULL) free(a->name);
 if(a->defn!=NULL) free(a->defn);
 free(a);
}

void free_tab(void)
{unsigned i;
 struct nlist *p, *q;
 F(i=0;i<HASHSIZE;++i)
   F(p=hashtab[i];p!=NULL; p=q)
       {q=p->next;
        free_node(p);
       }
}

/*undef: rimuove un nodo dalla tabella*/
int undef(char* name)
{struct nlist *pp, *p;
 unsigned hsv;
 if(name==NULL) R -1;
 hsv=hash(name);
 F(p=hashtab[hsv], pp=NULL;p!=NULL;pp=p, p=p->next)
   if(strcmp(name,p->name)==0)
         {if(pp==NULL)
               hashtab[hsv]=p->next; /*il primo */
          else pp->next=p->next;
          free_node(p);
          R 0;
         }
 R 1;
}

/*instal: inserisce il nome (name, defn) in hashtab*/
struct nlist* install(char* name, char* defn)
{struct nlist *np;
 unsigned hashval;
 if((np=lookup(name))==NULL) /*non trovata*/
  {np=malloc(sizeof(*np));
   if(np==NULL) R NULL;
   if((np->name=dupstr(name))==NULL)
              {free(np);
               R NULL;
              }
   if((np->defn=dupstr(defn))==NULL)
              {free(np->name);
               free(np);
               R NULL;
              }
   hashval=hash(name);
   np->next=hashtab[hashval];
   hashtab[hashval]=np;/*mette il nuovo nodo davanti a tutti*/
  }
 else
     {free(np->defn); /*annulla il precedente defn P*/
      np->defn=NULL;
      if((np->defn=dupstr(defn))==NULL)
              {undef(name);
               R NULL;
              }
     }
 return np;
}

int is_punct(int c)
{
 if( c=='<'||c=='>' ||c=='+' || c=='-'|| c=='&' || c=='^' ||
     c=='!'||c=='*' ||c=='=' || c=='|'|| c=='?' ) R 1;
 R 0;
}

char* gword(char* a)
{static char buf[100]={0};
 char *b=buf;
 int ip, cont=100;

 W( *a!=0 && isspace(*a)) ++a;
 ip= is_punct(*a) ? 1: 0;
 if(*a)
  F(*b++=*a++ ; --cont>0 && *a!=0; *b++=*a++)
   {
    if(isspace(*a)) break;
    if( ip && !is_punct(*a) ) break;
    if( !ip && !isalnum(*a) && *a!='_' && *a!='%')
                              break;
   }
 *b=0;
 R buf;
}

char* macro_s(char* bufr, char* buf)
{char c, *a=buf;
 char fmt[10], *z;
 int i=0;

 *bufr=0;
  label:
    if( !(is_punct(*a) && is_punct(a[1])) && strchr("=?<>+-",
*a)==NULL
     /* ( (z=strchr("=?<>+-", *a)) ==NULL ||
                  (z && !( (*a=='+' || *a=='-') && isdigit(a[1]) )
                  )
            )
     */
      )
       {sprintf(fmt, "%%%d", ++i);
        strncat(bufr, fmt, 100);
        W( *a )
          {if(*a==';') F(;*a; a++);
           else if(*a=='\"')
              {F(++a; *a!=0 && *a!='\"'; ++a);
               if(*a) ++a;
              }
           else if(*a=='\'')
              {F(++a; *a!=0 && *a!='\''; ++a);
               if(*a) ++a;
              }
           else if(*a=='[')
              {F(++a; *a!=0 && *a!=']'; ++a);
               --a;
              }
           else if( (is_punct(*a) && is_punct(a[1]) ) ||
                        (strchr("=?<>+-", *a) &&
                                !( ( *a=='+' || *a=='-') &&
isdigit(a[1]) )
                        )
                  )
                                 goto label;
           else if(isspace(*a)) a++;
           else ++a;
          }
       }
    else
      {strncat(bufr, " ", 100);
       strncat(bufr, gword(a), 100);
       strncat(bufr, " ", 100);
       F( ; *a!=0 && (is_punct(*a) || isspace(*a)) ; ++a);
      }
    if(*a) goto label;
 R bufr;
}

char* macro_sinv(char* buf, char* bufr)
{char wor[500]={0}, *a=bufr, *b, *w=wor, *c;
 int i, j;

 label:
   W(*a!=0 && *a!='%') *w++=*a++;
   if(*a=='%')
      {i=atoi(++a); j=1; b=buf;
       W(isdigit(*a)) ++a;
       lab:
           F(;*b && ( ( is_punct(*b)
                       && !( (*b=='-' || *b=='+') && isdigit(b[1]) )
                      )
                       || isspace(*b)
                    )
             ; ++b);
           c=b; // finisce il comando
           F(; *b; ++b) // caso operandi
              if(*b==';') F(;*b; b++);
              else if(*b=='\"')
                 {F(++b; *b!=0 && *b!='\"'; ++b);
                  if(*b) ++b;
                 }
              else if(*b=='\'')
                 {F(++b; *b!=0 && *b!='\''; ++b);
                  if(*b) ++b;
                 }
              else if(*b=='[')
                 {F(++b; *b!=0 && *b!=']'; ++b);
                  --b;
                 }
              else if((is_punct(*b) && is_punct(b[1])) ||
                           (strchr("=?<>+-", *b)) && !( (*b=='+' ||
*b=='-') && isdigit(b[1]) )
                           )
                 break;
           if(b>buf && isspace(b[-1]) ) --b;
           if(i==j++)
             {F(; c<b ; ) *w++=*c++;
              goto label;
             }
           if(*b) goto lab;
      }
   if(*a) goto label;
 *w=0;
 R strcpy(buf, wor);
}

int main(int x, char** a)
{int getword(char* , int , FILE* );
 int next_word_line(char* , int , FILE* );
 int next_defn(char* , int , FILE* );
 int getch(FILE*);
 void ungetch(int );
 int c, cp, cpp, i, inq=0;
 char word[MAXW], *w, *u;
 static char buf[500]={0}, bufr[100]={0}, *b;
 struct nlist *np;
 FILE *f_in, *f_out;
 if(x<2||a[1]==NULL||a[2]==NULL)
  {P("USO:\n>nome_prog nome_file_in nome_file_out\n"); R 0;}
 if((f_in=fopen(a[1],"r"))==NULL)
  {printf("\n ERRORE, impossibile leggere il file %s\n", a[1]);
   return 0;
  }
 if((f_out=fopen(a[2],"w"))==NULL)
  {printf("\n ER R ORE, impossibile scrivere il file %s\n", a[2]);
   fclose(f_in);
   return 0;
  }
 install( "pu", "push ");
 install( "po", "pop " );
 install( "%1 = %2" , "mov %1, %2");
 install( "a" , "eax");
 install( "b" , "ebx");
 install( "c" , "ecx");
 install( "d" , "edx");
 install( "\\\\", "\n");
 install( "**", "mul ");

 install( "%1 += %2", "add %1, %2");
 install( "%1 -= %2", "sub %1, %2");
 install( "w2", "dword");
 install( "ww", "word");
 install( "bb", "byte");
 install( "w4", "qword");

 install( "%1 <<= %2" , "shl %1, %2");
 install( "%1 >>= %2" , "shr %1, %2");
 install( "%1 && %2" , "test %1, %2");
 install( "%1 &= %2" , "and %1, %2");
 install( "%1 |= %2" , "or %1, %2");
 install( "%1 ^= %2" , "xor %1, %2");
 install( "%1 << %2" , "cmp %1, %2");
 install( "++", "inc ");
 install( "--", "dec ");
 install( "div" , "div ");
 
 install( "%1 <> %2", "cmp %1, %2 ");
 install( "%1 < %2 ? %3" , "cmp %1, %2 \n jb %3 ");
 install( "%1 > %2 ? %3" , "cmp %1, %2 \n ja %3 ");
 install( "%1 <= %2 ? %3", "cmp %1, %2 \n jbe %3 ");
 install( "%1 >= %2 ? %3", "cmp %1, %2 \n jae %3 ");
 install( "%1 == %2 ? %3", "cmp %1, %2 \n je %3 ");
 install( "%1 != %2 ? %3", "cmp %1, %2 \n jne %3 ");

 install( "%1 = %2 + %3", "mov %1, %2 \n add %1, %3 ");
 install( "%1 = %2 - %3", "mov %1, %2 \n sub %1, %3 ");

 F(c=getword(word, MAXW, f_in),cpp=EOF, b=buf, *b=0; ;
               cpp=c, c=getword(word, MAXW, f_in))
      {if(c==EOF || isspace(c))
         {if(c!=EOF && b>buf && b[-1]!='\n') *b++=c;
          if(c==EOF || word[0]=='\n')
                  {if(c!=EOF && b>buf) *--b=0;
                   else *b=0;
                   macro_s(bufr, buf);
              // P("buf=%s ", buf);
              // F(i=0; bufr[i]; ++i) P("%d[%c] ", bufr[i],
bufr[i]);
                   if( (w=gword(buf)) && *w != ';')
                     if((np=lookup(bufr))!=NULL)
                        {strncpy(bufr, np->defn, 100);
                         macro_sinv(buf, bufr);
                        }
                   //P("\n");
                   //F(i=0; buf[i]; ++i) P("%d[%c] ", buf[i], buf[i]);
                   //w=gword(buf);
                   //P(" gword(buf)==%d \n", *w );
                   if( (w=gword(buf)) && *w != ';')
                    {if( (w=strchr(buf, '%'))==NULL || (w &&
isdigit(w[1]))
                          || (w && (u=strchr(buf, ';')) && u<w )
)
                       if( (w=strchr(buf, ':'))==NULL ||
                         (w!=NULL && w[1]!=0 && !isspace((UC) w[1]))
)
                           fputs(" ", f_out);
                    }
                   else fputs(" ", f_out);
                   fputs(buf, f_out); fputs("\n", f_out);
                   *buf='\0'; b=buf;
                  }
          if(c==EOF) break;
         }
       else if(c=='\"'&& cpp!='\\')
              {F(w=word; *w; ) *b++=*w++;
               F(cp=c;(c=getch(f_in))!=EOF && !(c=='\"'&& cp!='\\');
cp=c)
                                             *b++=c;
               if(c=='\"') *b++='\"';
              }
       else if(c=='\''&& cpp!='\\')
              {F(w=word; *w; ) *b++=*w++;
               F(cp=c;(c=getch(f_in))!=EOF && !(c=='\''&& cp!='\\');
cp=c)
                                                *b++=c;
               if(c=='\'') *b++='\'';
              }
       else if(c==';')
              {F(w=word; *w; ) *b++=*w++;
               F(;(c=getch(f_in))!=EOF && c!='\n';)
                                      *b++=c;
               ungetch('\n');
              }
       else {if(c=='[') inq=1;
              if(c==']') inq=0;
              if((np=lookup(word))!=NULL)
                        F(w=np->defn; *w; ) *b++=*w++;
              else F(w=word; *w; ) *b++=*w++;
           // P("word=%s", word);
              if(word[0]==':' && inq==0)
                      {F(;(c=getch(f_in))!=EOF && isspace(c) &&
c!='\n';);
                       if(c!=EOF)
                           {if(c!='\n') ungetch(c);
                            if(!isdigit(c)) ungetch('\n');
                            continue;
                           }
                       if(c==EOF) break;
                       }
             }
      }
 fclose(f_in);
 fclose(f_out);
 free_tab();
 R 0;
}

#define BUFSIZE 100

int buf[BUFSIZE];
int bufp=0;

int getch(FILE* pnt)
{R (bufp>0) ? buf[--bufp] : fgetc(pnt);}

void ungetch(int c)
{if(bufp>=BUFSIZE)
   P("ungetch: troppi caratteri\n");
 else buf[bufp++]=c;
}

/*getword: legge la prossima parola o carattere
 dall'input*/
int getword(char* word, int lim, FILE* pnt)
{int c, cp;
 char *w=word, *b;
 int ip, led, max=lim;
        
 c = getch(pnt);
 if(c!=EOF) *w++=c;
 if(c=='\\')
   {
    W( lim>0 && (cp=getch(pnt))=='\\' ) max=lim+1;
    if(cp!=EOF) ungetch(cp);
    if(lim!=max)
       {*--w='\n'; w++; goto fine;}
   }
 if(!isalpha(c)&& c!='_'&& !isdigit(c) && !is_punct(c) )
    {if(isspace(c) && c!='\n')
      {cp=c;
       W(isspace(cp) && cp!='\n') cp=getch(pnt);
       if(cp!=EOF && (!isspace(cp) || cp=='\n') ) ungetch(cp);
      }
     *w='\0';
     R c;
    }
 ip= is_punct(c) ? 1: 0; /* ip=1 parola di punti*/
 F( ; --lim>0 && (c=getch(pnt))!=EOF ; *w++=c )
   {/* Spazi (in ogni caso) e non punteggiatura nel
       caso di parole di punteggiatura interrompono */
    if(isspace(c)) break;
    if(w>word && (w[-1]=='+' || w[-1]=='-') && isdigit(c)) ip=0;
    if( ip && !is_punct(c))
         {if( c!=EOF ) ungetch(c);
          if( c!=EOF && !isspace(c))
               ungetch(' ');
          goto fine;
         }
     if(c=='-' || c=='+')
         {if( isdigit( cp=getch(pnt) ) )
             {ungetch(cp);
              ungetch(c);
              ungetch(' ');
              goto fine;
             }
          if(cp!=EOF) ungetch(cp);
         }
    /* Nel caso di parole alfanumeriche una lettera
       non alfanumerica (non _ %) interrompe
    */
    if( !ip && !isalnum(c) && c!='_' && c!='%') break;
   }
 fine1:
 if(c!=EOF ) ungetch(c);
 fine:
 *w = '\0';
 R word[0];
}

/* Dividere le parole in due gruppi (per la costruzione di get_word):
1) Le parole che sono finite dai caratteri ' ' e in ascii dal
   9 al 13 compresi (da tutti gli spazi)
2) Le parole che sono finite da un carattere non spazio nel caso
   cha appartengano alla punteggiatura
*/

int next_word_line(char* word, int lim, FILE* pnt)
{int c;
 if(word==NULL||pnt==NULL) R 0;
 W( isspace(c=getword(word, lim, pnt)) && c!='\n');
 R c;
}

int next_defn(char* word, int lim, FILE* pnt)
{int c, cp, i;
 if(word==NULL||pnt==NULL) R 0;
 word[0]='\0';
 W( isspace(c=getch(pnt)) && c!='\n');
 if(c==EOF||c=='\n') R c;
 word[0]=c;
 F(cp=c,i=0;i<lim &&(c=getch(pnt))!=EOF && !(c=='\n'&&cp!='\\');cp=c)
            if(c!='\n'&&c!='\\') word[++i]=c;
 word[++i]='\0';
 R c;
}



Relevant Pages