Скачиваний:
34
Добавлен:
15.09.2014
Размер:
4.21 Кб
Скачать
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;

# define MMX_REGISTER_QUANTITY 8
int foul=0;

// Получение значения регистра
_int64 get_register(int number)
{
_int64 result=0;
switch(number)
{
	case 0:
		_asm{MOVQ  result,MM0} 
		break;
	case 1:
		_asm{MOVQ  result,MM1} 
		break;
	case 2:
		_asm{MOVQ  result,MM2} 
		break;
	case 3:
		_asm{MOVQ  result,MM3} 
		break;
	case 4:
		_asm{MOVQ  result,MM4} 
		break;
	case 5:
		_asm{MOVQ  result,MM5} 
		break;
	case 6:
		_asm{MOVQ  result,MM6} 
		break;
	case 7:
		_asm{MOVQ  result,MM7} 
		break;
}
return result;
}

// Занесение значения в регистр
void set_register(int number, _int64 value)
{
switch(number)
{
	case 0:
		_asm{MOVQ  MM0,value} 
		break;
	case 1:
		_asm{MOVQ  MM1,value} 
		break;
	case 2:
		_asm{MOVQ  MM2,value} 
		break;
	case 3:
		_asm{MOVQ  MM3,value} 
		break;
	case 4:
		_asm{MOVQ  MM4,value} 
		break;
	case 5:
		_asm{MOVQ  MM5,value} 
		break;
	case 6:
		_asm{MOVQ  MM6,value} 
		break;
	case 7:
		_asm{MOVQ  MM7,value} 
		break;
}
}

bool operation (char* symbol)
{
int sp_save;
_int64 null=0;

if (!strcmp(symbol,"+")||!strcmp(symbol,"ADD"))
{
_asm{
	MOVQ  MM2,MM0
	PADDQ  MM2,MM1
}
return true;
}	

if (!strcmp(symbol,"-")||!strcmp(symbol,"SUB"))
{
_asm{
	mov  sp_save,esp     // сохранение регистра стека
	MOVQ  MM2,MM0        
	PCMPGTD  MM2,MM1     //заполняет ММ2 1-ми,если сод. ММ2<ММ1,и наоборот
	MOVD  eax,MM2
	cmp eax,0
	je EXC               //если ММ2 заполнен 0-ми,то отнимаем от ММ1 ММ2
	MOVQ  MM2,MM0
	PSUBQ  MM2,MM1
	call QUIT
	EXC:
	mov  eax,1
	mov  foul,eax
	MOVQ  MM2,MM1
	PSUBQ  MM2,MM0
	QUIT:
	mov  esp,sp_save
}
return true;
}

if (!strcmp(symbol,"*")||!strcmp(symbol,"MUL"))
{
_asm{
	mov  sp_save,esp
	MOVQ  MM4,MM0
	MOVQ  MM5,MM1
//анализируем 1-й множитель
	MOVQ  MM2,MM4
	PCMPGTD  MM2,null    //заполняет ММ2 1-ми,если сод. ММ2>0,и наоборот
	MOVD  eax,MM2
	cmp eax,0            
	je EXC2              //если ММ2<0,т.е.  если 1-й множитель <0  
	call CONT            //если 1-й множитель >0 
	EXC2:
	mov  eax,foul
	add  eax,1
	mov  foul,eax
	MOVQ  MM2,MM4
	MOVQ  MM4,null
	PSUBQ  MM4,MM2   //делаем 1-й множитель положительным(отнимаем от 0 отр. 1-й множитель)
//анализируем 2-й множитель
	CONT:
	MOVQ  MM2,MM5
	PCMPGTD  MM2,null     //заполняет ММ2 1-ми,если сод. ММ2>0,и наоборот
	MOVD  eax,MM2
	cmp eax,0              //если ММ2<0,т.е.  если 2-й множитель <0  
	je EXC3
	call CONT2         //если 2-й множитель >0 
	EXC3:
	mov  eax,foul
	add  eax,1
	mov  foul,eax
	movq  MM2,MM5        
	MOVQ  MM5,null
	PSUBQ  MM5,MM2    //делаем 2-й множитель положительным(отнимаем от 0 отр. 1-й множитель)

	CONT2:
	MOVQ  MM2,MM4     //наше 1-е слагаемое,сделанное положительным
	PMADDWD MM2,MM5  //умножаем на 2-е,сделонное положительным
	mov  esp,sp_save
}
return true;
}

if (!strcmp(symbol,"/"))
{
_int64 result, divident;
_asm{
	MOVQ  result,MM0
	MOVQ  divident,MM1
}
if(divident==0) return false;
result/=divident;
_asm{
	MOVQ  MM2,result
}
return true;

}
return false;
}


int main()
{
char sign[4];
int number;
int mode=0;

while(1)
{
system("cls");
cout << "MMX:\n" << endl;

for (int i=0; i<MMX_REGISTER_QUANTITY; i++)
	cout << "MM" << i << ": " << get_register(i) << endl;


if (!mode)
{
	cout << "Input first number: "; 
	cin>>number;

	set_register(0,number); 
	mode++; 
	continue;
}

if (mode==1)
{
	cout << "First number: " << get_register(0) << endl;
	cout << "Input znak: "; 
	cin>>sign;
	mode++; 
	continue;
}

if (mode==2)
{
	cout << "First number: " << get_register(0) << endl << "Znak: " << sign << endl;
	cout << "Input second number: "; 
	cin>>number; 
	set_register(1,number);

if (!operation(sign)) 
{
	cout << endl <<"Not known operation!"; 
	getch();
	mode=0; 
	continue;
}

mode++;
continue;
}

if (mode==3)
{
	cout << get_register(0) << " " << sign << " " << get_register(1) << " = ";
	if (foul==1)cout << "-";
	cout << get_register(2); 
	getch(); 
	foul=0; 
	mode=0; 
	continue;
}
}

return 0;}