Re: A sample RosAsm macro (actually a whole set)
From: RoWsRaIrTiEo (non_at_esist.eeee)
Date: 02/13/04
- Next message: Annie: "Re: A sample RosAsm macro (actually a whole set)"
- Previous message: RoWsRaIrTiEo : "Re: shr for division not quite working"
- In reply to: Woody: "Re: A sample RosAsm macro (actually a whole set)"
- Next in thread: C: "Re: A sample RosAsm macro (actually a whole set)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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;
}
- Next message: Annie: "Re: A sample RosAsm macro (actually a whole set)"
- Previous message: RoWsRaIrTiEo : "Re: shr for division not quite working"
- In reply to: Woody: "Re: A sample RosAsm macro (actually a whole set)"
- Next in thread: C: "Re: A sample RosAsm macro (actually a whole set)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|