case OP_SUB : *op1 -= *op2; pswz = (*op1 == 0); break;
case OP_PUSH: push(*op1); regval[RSP]++; break;
case OP_POP : *op1 = pop(); break;
case OP_RET : regval[RIP] = pop(); break;
case OP_OR : *op1 |= *op2; break;
case OP_XOR : *op1 ^= *op2; break;
case OP_AND : *op1 &= *op2; break;
case OP_NOT : *op1 = !*op1; break;
}
}
int strconsist(char *s, char c)
{
while(*s)
if(*s++ == c)
return 1;
return 0;
}
char *parse(char *buf, char *str)
{
char c;
while(*str)
{
c = *str;
if(!strconsist(separators, c))
{
if(strconsist(signs, c))
{
buf[0] = c;
buf[1] = 0;
parsetyp = PT_SIGN;
return str+1;
}
while(*str &&
(!strconsist(separators, *str)) &&
(!strconsist(signs, *str)))
*buf++ = *str++;
*buf = 0;
parsetyp = PT_WORD;
return str;
}
str++;
}
*buf = 0;
parsetyp = PT_EOST;
return str;
}
int findstr(char *tab[], char *it)
{
int cmdidx;
cmdidx = 0;
while(tab[cmdidx])
{
if(strcomp(tab[cmdidx], it))
return cmdidx;
cmdidx++;
}
return -1;
}
void main(void)
{
int opcode, op1num, op2num, i,index, n;
char *parsep;
restart:
printf("\nПрограмма обрабатывает команды\n");
for (index = 0; index < sizeof(mnemonics)/2; index++)
printf ("%s,",mnemonics[index]);
printf("\n\nДля выхода из программы,не вводя команды нажмите ENTER ");
printf("\n\nOperation > ");
gets(cmdbuf);
strupcase(cmdbuf);
if(!cmdbuf[0])
goto quit;
parsep = cmdbuf;
do {
parsep = parse(lexbuf, parsep);
if(parsetyp != PT_WORD)
{
printf("Must be command mnemonic");
goto restart;
}
if(0 > (opcode = findstr(mnemonics, lexbuf)))
{
printf("Wrong command");
goto restart;
}
parsep = parse(lexbuf, parsep);
if(!operandcount[opcode])
{
if(parsetyp != PT_SIGN)
{
printf("This commands does not request an operands");
goto restart;
}
if(lexbuf[0] != ';')
{
printf("Must be command delimiter (;) but not %c", lexbuf[0]);
goto restart;
}
goto runcmd;
}
if(parsetyp != PT_WORD)
{
printf("First operand be register");
printf(" Got: %d '%s'", parsetyp, lexbuf);
goto restart;
}
if(0 > (op1num = findstr(registers, lexbuf)))
{
printf("Unknown register");
goto restart;
}
if(operandcount[opcode] == 1)
goto runcmd;
parsep=parse(lexbuf,parsep);
if (lexbuf[0]!=',')
{
printf("Must be ','");
goto restart;
}
parsep = parse(lexbuf, parsep);
if(parsetyp != PT_WORD)
{
printf("Second operand be register or number");
goto restart;
}
if(0 > (op2num = findstr(registers, lexbuf)))
{
if(strtoi(lexbuf, &n))
{
printf("Unknown register or bad number");
goto restart;
}
op2num = RIMM;
regval[RIMM] = n;
}
runcmd:
execcmd(opcode, ®val[op1num], ®val[op2num]);
for(i = 0; i < (sizeof(registers)/2 - 1); i++)
{
printf("\t%s=%X(%d) ", registers[i], regval[i],regval[i]);
if (!((i+1) % 3)) printf("\n");
}
printf("\n");
for(i = 1; i < 16; i++)
{
if(regval[RSP] < i)
break;
printf("ST[%d]=%.2X(%d) ",regval[RSP] - i, stack[regval[RSP] - i],stack[regval[RSP] - i] );
}
printf("\n");
goto restart;
} while(parsetyp);
quit:;
}
6. Результати виконання програми.
Результатом виконання програми є вміст імітованих регістрів :
Програма обробляє команди
MOV, DEC, INC, ADD, SUB, PUSH, POP, RET, OR, XOR, AND, NOT.
Для виходу з програми, не вводячи команди натисніть ENTER.
Operation > mov cx,-1
AX=0(0) BX=0(0) CX=FFFF(-1)
DX=0(0) SP=0(0) BP=0(0)
SI=0(0) DI=0(0) IP=0(0)
Operation >push cx
AX=0(0) BX=0(0) CX=FFFF(-1)
DX=0(0) SP=1(1) BP=0(0)
SI=0(0) DI=0(0) IP=0(0)
ST[0]=FFFF(-1)
Operation >pop ax
AX=FFFF(-1) BX=0(0) CX=FFFF(-1)
DX=0(0) SP=FFFF(-1) BP=0(0)
SI=0(0) DI=0(0) IP=0(0)
7. Висновки з проробленої роботи: У процесі лабораторної роботи були вивчені принципи написання програм, що імітують виконання команд і директив язика асемблера.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.