Смекни!
smekni.com

Эмуляция команды математического сопроцессора FSUB (стр. 4 из 4)

Таблица 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&bsol;n2 - fsub n&bsol;n3 - fsub st(n), st(n)&bsol;n4 - fld&bsol;n0 - выход&bsol;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("Введите непосредственный операнд: &bsol;n");

fld(reg,sreg,creg,twr,0,9);

print_st(reg,sreg,creg,twr,0);

break;

case 3:

int s1;

int s2;

printf("Введите номера регистров, которые вы хотите использовать: &bsol;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("Добовлнение значения в стек: &bsol;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&bsol;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&bsol;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;

}