📄 gas2masm.c
字号:
//
// gas to MASM source code converter
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TOKENS 100
#define MAX_TOKEN_LENGTH 1024
#define LF 0x0A
typedef enum {NOT_WHITESPACE, WHITESPACE, TOKEN_AVAILABLE, LINE_DONE, FILE_DONE, PARSED_OKAY} tokenstat;
typedef enum {NOSEG, DATASEG, TEXTSEG} segtype;
int tokennum;
int inline, outline;
char *token;
char tokens[MAX_TOKENS][MAX_TOKEN_LENGTH+1];
segtype currentseg = NOSEG;
typedef struct {
char *text;
char *emit;
int numtokens;
void (*parsefunc) (void);
} parsefield;
void errorexit (void);
//==============================================
typedef struct {
char *text;
char *emit;
int len;
} regdesc;
regdesc reglist[] = {
{"%eax", "eax", 4},
{"%ebx", "ebx", 4},
{"%ecx", "ecx", 4},
{"%edx", "edx", 4},
{"%esi", "esi", 4},
{"%edi", "edi", 4},
{"%ebp", "ebp", 4},
{"%esp", "esp", 4},
{"%ax", "ax", 3},
{"%bx", "bx", 3},
{"%cx", "cx", 3},
{"%dx", "dx", 3},
{"%si", "si", 3},
{"%di", "di", 3},
{"%bp", "bp", 3},
{"%sp", "sp", 3},
{"%al", "al", 3},
{"%bl", "bl", 3},
{"%cl", "cl", 3},
{"%dl", "dl", 3},
{"%ah", "ah", 3},
{"%bh", "bh", 3},
{"%ch", "ch", 3},
{"%dh", "dh", 3},
{"%st(0)", "st(0)", 6},
{"%st(1)", "st(1)", 6},
{"%st(2)", "st(2)", 6},
{"%st(3)", "st(3)", 6},
{"%st(4)", "st(4)", 6},
{"%st(5)", "st(5)", 6},
{"%st(6)", "st(6)", 6},
{"%st(7)", "st(7)", 6},
};
int numregs = sizeof (reglist) / sizeof (reglist[0]);
//==============================================
void emitanoperand (int tnum, char *type, int notdata)
{
int i, index, something_outside_parens, regfound;
int parencount;
char *pt;
char temp[MAX_TOKEN_LENGTH+1];
pt = tokens[tnum];
if (pt[0] == '%')
{
// register
for (i=0 ; i<numregs ; i++)
{
if (!strcmpi (pt, reglist[i].text))
{
printf ("%s", reglist[i].emit);
return;
}
}
fprintf (stderr, "Error: bad register %s\n", pt);
errorexit ();
}
else if (pt[0] == '$')
{
// constant
if (pt[1] == '(')
{
if ((pt[2] > '9') || (pt[2] < '0'))
{
i = 2;
printf ("offset ");
parencount = 1;
while ((pt[i] != ')') || (parencount > 1))
{
if (!pt[i])
{
fprintf (stderr, "mismatched parens");
errorexit ();
}
if (pt[i] == ')')
parencount--;
else if (pt[i] == '(')
parencount++;
printf ("%c", pt[i]);
i++;
}
}
else
{
pt++;
parencount = 1;
for (i=1 ; (pt[i] != ')') || (parencount > 1) ; i++)
{
if (!pt[i])
{
fprintf (stderr, "mismatched parens");
errorexit ();
}
if (pt[i] == ')')
parencount--;
else if (pt[i] == '(')
parencount++;
}
pt[i] = 0;
if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
{
printf ("0%sh", &pt[3]);
}
else
{
printf ("%s", &pt[1]);
}
}
}
else if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
{
printf ("0%sh", &pt[3]);
}
else if ((pt[1] >= '0') && (pt[1] <= '9'))
{
printf ("%s", &pt[1]);
}
else
{
printf ("offset %s", &pt[1]);
}
}
else if (!notdata && ((pt[0] >= '0') && (pt[0] <= '9')))
{
pt--;
if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
{
printf ("0%sh", &pt[3]);
}
else
{
printf ("%s", &pt[1]);
}
}
else
{
// must be a memory location
strcpy (temp, type);
index = strlen (temp);
if (notdata)
temp[index++] = '[';
something_outside_parens = 0;
while (*pt)
{
if (index > (MAX_TOKEN_LENGTH - 10))
{
fprintf (stderr, "Error: operand too long %s\n",
tokens[tnum]);
errorexit ();
}
if (*pt != ')')
{
if (*pt == '(')
{
if (something_outside_parens)
temp[index++] = '+';
}
else if (*pt == '%')
{
regfound = 0;
for (i=0 ; i<numregs ; i++)
{
if (!strnicmp (pt, reglist[i].text,
reglist[i].len))
{
strcpy (&temp[index], reglist[i].emit);
index += strlen (reglist[i].emit);
pt += strlen (reglist[i].text) - 1;
regfound = 1;
break;
}
}
if (!regfound)
{
fprintf (stderr, "Error: bad register %s\n", pt);
errorexit ();
}
}
else if (*pt == ',')
{
pt++;
if ((*pt >= '1') && (*pt <= '8'))
{
temp[index++] = '*';
temp[index++] = *pt;
}
else if (*pt != ')')
{
if (temp[index-1] != '+')
temp[index++] = '+';
}
}
else
{
something_outside_parens = 1;
// handle hexadecimal constants in addresses
if ((*pt == '0') &&
((*(pt+1) == 'x') || (*(pt+1) == 'X')))
{
pt += 2;
do
{
temp[index++] = *pt++;
} while (((*pt >= '0') && (*pt <= '9')) ||
((*pt >= 'a') && (*pt <= 'f')) ||
((*pt >= 'A') && (*pt <= 'F')));
pt--;
temp[index++] = 'h';
}
else
{
temp[index++] = *pt;
}
}
}
pt++;
}
if (notdata)
temp[index++] = ']';
temp[index] = 0;
printf ("%s", temp);
}
}
void datasegstart (void)
{
if (currentseg == DATASEG)
return;
if (currentseg == TEXTSEG)
printf ("_TEXT ENDS\n");
printf ("_DATA SEGMENT");
currentseg = DATASEG;
}
void textsegstart (void)
{
if (currentseg == TEXTSEG)
return;
if (currentseg == DATASEG)
printf ("_DATA ENDS\n");
printf ("_TEXT SEGMENT");
currentseg = TEXTSEG;
}
void emitdata (void)
{
int i;
for (i=1 ; i<(tokennum-1) ; i++)
printf (" %s,", tokens[i]);
printf (" %s", tokens[tokennum-1]);
}
void emitonedata (void)
{
printf (" %s", tokens[1]);
}
void emitonecalldata (void)
{
int i, isaddr, len;
if (tokens[1][0] == '*')
{
printf (" dword ptr[%s]", &tokens[1][1]);
}
else
{
isaddr = 0;
len = strlen(tokens[1]);
for (i=0 ; i<len ; i++)
{
if (tokens[1][i] == '(')
{
isaddr = 1;
break;
}
}
if (!isaddr)
{
printf (" near ptr %s", tokens[1]);
}
else
{
emitanoperand (1, " dword ptr", 1);
}
}
}
void emitonejumpdata (void)
{
int i, isaddr, len;
if (tokens[1][0] == '*')
{
printf (" dword ptr[%s]", &tokens[1][1]);
}
else
{
isaddr = 0;
len = strlen(tokens[1]);
for (i=0 ; i<len ; i++)
{
if (tokens[1][i] == '(')
{
isaddr = 1;
break;
}
}
if (!isaddr)
{
printf (" %s", tokens[1]);
}
else
{
emitanoperand (1, " dword ptr", 1);
}
}
}
void emitexterndef (void)
{
printf (" %s:dword", tokens[1]);
}
void nooperands (void)
{
}
void emitoneoperandl (void)
{
printf (" ");
emitanoperand (1, "ds:dword ptr", 1);
}
void emitoneoperandb (void)
{
printf (" ");
emitanoperand (1, "ds:byte ptr", 1);
}
void emitoneoperandw (void)
{
printf (" ");
emitanoperand (1, "ds:word ptr", 1);
}
void emittwooperandsl (void)
{
printf (" ");
emitanoperand (2, "ds:dword ptr", 1);
printf (",");
emitanoperand (1, "ds:dword ptr", 1);
}
void emittwooperandsb (void)
{
printf (" ");
emitanoperand (2, "ds:byte ptr", 1);
printf (",");
emitanoperand (1, "ds:byte ptr", 1);
}
void emittwooperandsw (void)
{
printf (" ");
emitanoperand (2, "ds:word ptr", 1);
printf (",");
emitanoperand (1, "ds:word ptr", 1);
}
void emit_0_or_1_operandsl (void)
{
if (tokennum == 2)
{
printf (" ");
emitanoperand (1, "ds:dword ptr", 1);
}
}
void emit_1_or_2_operandsl (void)
{
int j;
if (tokennum == 2)
{
printf (" ");
emitanoperand (1, "ds:dword ptr", 1);
}
else if (tokennum == 3)
{
printf (" ");
emitanoperand (2, "ds:dword ptr", 1);
printf (",");
emitanoperand (1, "ds:dword ptr", 1);
}
else
{
fprintf (stderr, "Error: too many operands\n");
for (j=0 ; j<tokennum ; j++)
fprintf (stderr, "%s\n", tokens[j]);
fprintf (stderr, "\n");
errorexit ();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -