Таблица 4.6
Название регистра | Мантисса | Порядок |
St0 | 8,7952 | 2 |
St1 | 4,562 | 3 |
St2 | денормализованый операнд | 0 |
St3 | 0 | 0 |
St4 | бесконечность | 5 |
St5 | 1,12 | 1 |
St6 | нечисло | 0 |
St7 | пусто | 0 |
После 6 теста ( fsub st0, st6); twr =98B; swr =600E (флаг IE = 1)
cwr =D
Таблица 4.7
Название регистра | Мантисса | Порядок |
St0 | 8,7952 | 2 |
St1 | 4,562 | 3 |
St2 | денормализованый операнд | 0 |
St3 | 0 | 0 |
St4 | бесконечность | 5 |
St5 | 1,12 | 1 |
St6 | нечисло | 0 |
St7 | пусто | 0 |
После 7 теста ( fsub st0, st7).
twr =98B
swr =410E (флаг IE = 1, SF = 1)
cwr =D
Таблица 4.8
Название регистра | Мантисса | Порядок |
St0 | 8,7952 | 2 |
St1 | 4,562 | 3 |
St2 | денормализованый операнд | 0 |
St3 | 0 | 0 |
St4 | бесконечность | 5 |
St5 | 1,12 | 1 |
St6 | нечисло | 0 |
St7 | пусто | 0 |
После 8 теста ( fsub st0, st4).
twr =98B
swr =600E (флаг IE = 1)
cwr =D
Таблица 4.9
Название регистра | Мантисса | Порядок |
St0 | 8,7952 | 2 |
St1 | 4,562 | 3 |
St2 | денормализованый операнд | 0 |
St3 | 0 | 0 |
St4 | бесконечность | 5 |
St5 | 1,12 | 1 |
St6 | нечисло | 0 |
St7 | пусто | 0 |
Заключение
В результате проделанной работы была написана программа, по своей сути, дублирующая команду математического сопроцессора fsub, а также её вариации. Были изучены и применены на практике в виде эмуляции 3 регистра. Регистор тегов, регистр команд и регистр состояний.
Была изучена система команд процессора 80х87 и принципы работы процессоров. Было получено представление и содержании такого устройства как процессор, что до не давнего времени было известно на уровне "черного ящика".
П.1. Текст программы
#include<iostream>
#include<string>
#include<windows.h>
struct bits
{
unsigned char b0 : 1;
unsigned char b1 : 1;
unsigned char b2 : 1;
unsigned char b3 : 1;
unsigned char b4 : 1;
unsigned char b5 : 1;
unsigned char b6 : 1;
unsigned char b7 : 1;
};
union bait_tab
{
bits bit;
unsigned char bait;
};
struct regs
{
unsigned IE: 1; // Ошибка недействительной операции;
unsigned DE: 1; // Ошибка денормализованного операнда;
unsigned ZE: 1; // Ошибка деления на ноль;
unsigned OE: 1; // Ошибка антипереполнения;
unsigned UE: 1; // Ошибка переполнения;
unsigned PE: 1; // Ошибка точности;
unsigned SF: 1; // Бит ошибки работы со стеком;
unsigned ES: 1; // Бит суммарной ошибки;
unsigned C0: 1; // Бит признака (Condition Code);
unsigned C1: 1; // Бит признака (Condition Code);
unsigned C2: 1; // Бит признака (Condition Code);
unsigned TOP:3; // Указатель регистра текущей вершины стека;
unsigned C3: 1; // Бит признака (Condition Code);
unsigned B: 1; // Бит занятости.
};
union _sreg
{
regs data;
unsigned short int sreg;
};
union _creg
{
struct
{
//маски
unsigned IM: 1; // Маска недействительной операции;
unsigned DM: 1; // Маска денормализованного операнда;
unsigned ZM: 1; // Маска деления на ноль;
unsigned OM: 1; // Маска антипереполнения;
unsigned UM: 1; // Маска переполнения;
unsigned PM: 1; // Маска точности;
unsigned PC: 2; // Поле управления точностью;
unsigned RC: 2; // Поле управления округлением.
} data;
unsigned short int creg;
};
union _twr
{
struct
{
unsigned char pr0:2;// 00 - занят допустимым не нулевым значением
//unsigned char pr1:2;// 01 - содержит нулевое значение
//unsigned char pr2:2;// 10 - содержит специальное численное значение
//unsigned char pr3:2;// 11 - регистр пуст
//unsigned char pr4:2;
//unsigned char pr5:2;
//unsigned char pr6:2;
//unsigned char pr7:2;
} data[8];
unsigned short int twr;
};
union ud16
{
bait_tab data[2];
short val;
};
union ud32
{
bait_tab data[4];
int val;
};
union ud64
{
bait_tab data[8];
_int64 val;
};
struct ud80
{
ud64 mant;
ud16 exp;
};
union str
{
bait_tab data[10];
ud80 val;
};
int fld(str reg[],_sreg &sreg,_creg creg,_twr twr,int st0 ,int stimm);
int print_st(str reg[],_sreg sreg,_creg creg,_twr twr,int id);
int fsub(str reg[],_sreg &sreg,_creg creg,_twr twr,int fl,int s1, int s2);
int main()
{
str reg[9]={};
_sreg sreg;
_creg creg;
_twr twr;
setlocale(LC_ALL,"Russian");
int d = -1;
sreg.sreg = 0;
creg.creg = 0;
sreg.data.TOP = 7;
creg.data.PC = 3;
twr.twr = 0xffff;
memset(reg,0,sizeof(reg));
while(d != 0)
{
printf("1 - fsub\n2 - fsub n\n3 - fsub st(n), st(n)\n4 - fld\n0 - выход\n");
scanf("%d",&d);
switch (d)
{
case 1:// fsub========================================================================================
fsub(reg,sreg,creg,twr,1,0,0);
//print_st(reg,sreg,creg,twr,0);
break;
case 2:
printf("Введите непосредственный операнд: \n");
fld(reg,sreg,creg,twr,0,9);
print_st(reg,sreg,creg,twr,0);
break;
case 3:
int s1;
int s2;
printf("Введите номера регистров, которые вы хотите использовать: \n");
scanf("%d %d",&s1,&s2);
//fld(reg,sreg,creg,twr,s1,0);
//fld(reg,sreg,creg,twr,s2,0);
fsub(reg,sreg,creg,twr,1,s1,s2);
break;
case 4:
printf("Добовлнение значения в стек: \n");
fld(reg,sreg,creg,twr,0,0);
break;
}
}
}
int fld(str reg[],_sreg &sreg,_creg creg,_twr twr,int st0 ,int stimm)
{
short p = 0;
char l[10];
_int64 i = 0;
scanf("%s",&l);
for(int m = 0; m <= strlen(l); m++)
{
if ((l[m] == '0')&&(p <= 0))
{
p--;
}
else
{
if ((i == 0)&&(l[m] != ','))p++;
}
if (l[m] == ',')
{
for(int e = m; e < strlen(l); e++)
{
l[e] = l[e+1];
}
char* ends;
i = strtol(l,&ends,10);
if (l[m] != '0')break;
}
}
/*if (p > 0)
{p++;}
else
{p--;}*/
if (i != 0)
{
twr.data[st0].pr0 &= 0;
}
else
{twr.data[st0].pr0 |= 1;}
p--;
if (stimm == 0)
{
if (st0 != 0)
{
reg[st0].val.mant.val = i;
reg[st0].val.exp.val = p;
}
else
{
reg[sreg.data.TOP].val.mant.val = i;
reg[sreg.data.TOP].val.exp.val = p;
sreg.data.TOP =sreg.data.TOP - 1;
}
}
else
{
reg[8].val.mant.val = i;
reg[8].val.exp.val = p;
fsub(reg,sreg,creg,twr,2,0,0);
}
return 0;
}
int print_st(str reg[],_sreg sreg,_creg creg,_twr twr, int id)
{
int ssn;
if (id != 0)
{
ssn = id;
}
else
{
ssn = sreg.data.TOP;
}
double a = (double)reg[ssn].val.mant.val;
short b = reg[ssn].val.exp.val;
for (int i = 0; i <= abs(b); i++)
{
a /=10;
}
printf("%10.5f\n",a);
return 0;
}
int fsub(str reg[],_sreg &sreg,_creg creg,_twr twr,int fl, int s1,int s2)
{
_int64 a;
short am;
_int64 b;
short bm;
int sn1;
int sn2;
if (fl == 1)
{
if ((s2 == 0)&&(s1 == 0))
{
//sn1 = sreg.data.TOP + 2;
//sn2 = sreg.data.TOP + 1 ;
sn1 = 7;
sn2 = 6;
}
else
{
sn1 = sreg.data.TOP + s1;
sn2 = sreg.data.TOP + s2;
}
a = reg[sn1].val.mant.val;
am = reg[sn1].val.exp.val;
b = reg[sn2].val.mant.val;
bm = reg[sn2].val.exp.val;
}
else
{
a = reg[sreg.data.TOP +1].val.mant.val;
am = reg[sreg.data.TOP +1].val.exp.val;
b = reg[8].val.mant.val;
bm = reg[8].val.exp.val;
}
short dm = am - bm;
if (a > b)
{
for(int i = 0; i < dm; i++)
{
a *= 10;
}
//reg[sn1].val.exp.val+=dm;
}
else
{
for(short n = 0; n <= (-1)*dm; n++)
{
b *= 10;
}
if (fl == 1)
{
reg[sn1].val.exp.val += (-1)*dm;
}
else
{
reg[sreg.data.TOP +1].val.exp.val += (-1)*dm;
}
}
a-= b;
//printf("%d\n",a);
if (fl == 1)
{
reg[sn1].val.mant.val = a;
//sreg.data.TOP+=2;
print_st(reg,sreg,creg,twr,sn1);
}
else
{
reg[sreg.data.TOP].val.mant.val = a;
//sreg.data.TOP+=1;
}
return 0;
}