实验一基本算术运算
计算机组成原理实验(接线、实验步骤)

计算机组成原理实验(接线、实验步骤)实验⼀运算器[实验⽬的]1.掌握算术逻辑运算加、减、乘、与的⼯作原理;2.熟悉简单运算器的数据传送通路;3.验证实验台运算器的8位加、减、与、直通功能;4.验证实验台4位乘4位功能。
[接线]功能开关:DB=0 DZ=0 DP=1 IR/DBUS=DBUS接线:LRW:GND(接地)IAR-BUS# 、M1、M2、RS-BUS#:接+5V控制开关:K0:SW-BUS# K1:ALU-BUSK2:S0 K3:S1 K4:S2K5:LDDR1 K6:LDDR2[实验步骤]⼀、(81)H与(82)H运算1.K0=0:SW开关与数据总线接通K1=0:ALU输出与数据总线断开2.开电源,按CLR#复位3.置数(81)H:在SW7—SW0输⼊10000001→LDDR2=1,LDDR1=0→按QD:数据送DR2置数(82)H:在SW7—SW0输⼊10000010→LDDR2=0,LDDR1=1→按QD:数据送DR1 4.K0=1:SW开关与数据总线断开K1=1:ALU输出与数据总线接通5. S2S1S0=010:运算器做加法(观察结果在显⽰灯的显⽰与进位结果C的显⽰)6.改变S2S1S0的值,对同⼀组数做不同的运算,观察显⽰灯的结果。
⼆、乘法、减法、直通等运算1.K0K1=002.按CLR#复位3.分别给DR1和DR2置数4.K0K1=115. S2S1S0取不同的值,执⾏不同的运算[思考]M1、M2控制信号的作⽤是什么?运算器运算类型选择表选择操作S2 S1 S00 0 0 A&B0 0 1 A&A(直通)0 1 0 A+B0 1 1 A-B1 0 0 A(低位)ΧB(低位)完成以下表格ALU-BUS SW-BUS# 存储器内容S2S1S0 DBUS C输⼊时:计算时:DR1:01100011DR2:10110100(与)DR1:10110100DR2:01100011(直通)DR1:01100011DR2:01100011(加)DR1:01001100DR2:10110011(减)DR1:11111111DR2:11111111(乘)实验⼆双端⼝存储器[实验⽬的]1.了解双端⼝存储器的读写;2.了解双端⼝存储器的读写并⾏读写及产⽣冲突的情况。
南邮数据结构实验一

实验报告(2014 / 2015 学年第二学期)课程名称数据结构实验名称线性表的基本运算及多项式的算术运算实验时间2015 年9 月28 日指导单位计算机科学与技术系指导教师黄海平学生姓名陈明阳班级学号Q学院(系) 贝尔英才专业信息科技强化班实验报告~SeqList() { delete[] elements; }bool IsEmpty() const;int Length() const;bool Find(int i, T& x) const;int Search(T x) const;bool Insert(int i, T x);bool Delete(int i);bool Update(int i, T x);void Output(ostream& out)const;private:int maxLength;T *elements;};template<class T>SeqList<T>::SeqList(int mSize){maxLength = mSize;elements = new T[maxLength];n = 0;}template<class T>bool SeqList<T>::IsEmpty() const{return n == 0;}template<class T>int SeqList<T>::Length()const{return n;}template<class T>bool SeqList<T>::Find(int i, T& x)const{if (i<0 || i>n - 1){cout <<"out of bounds"<< endl; return false;}x = elements[i];return true;}template<class T>int SeqList<T>::Search(T x)const{for (int j = 0; j < n; j++)if (elements[j] == x)return j;return -1;}template<class T>bool SeqList<T>::Insert(int i, T x){if (i<-1 || i>n - 1){cout <<"out of bounds"<< endl;return false;}if (n == maxLength){cout <<"over flow"<< endl;return false;}for (int j = n - 1; j > i; j--)elements[j + 1] = elements[j];elements[i + 1] = x;n++;return true;}template<class T>bool SeqList<T>::Delete(int i){if (i<0 || i>n - 1){cout <<"out of bounds"<< endl;return false;}if (!n){cout <<"over flow"<< endl;return false;}for (int j = i+1; j <n; j--)elements[j -1] = elements[j];n--;return true;}template<class T>bool SeqList<T>::Update(int i, T x){if (i<0 || i>n - 1){cout <<"out of bounds"<< endl;return false;}elements[i] = x;return true;}template<class T>void SeqList<T>::Output(ostream& out)const{for (int i = 0; i < n; i++)out << elements[i] << " ";out<< endl;}源.cpp:#include"seqlist.h"const int SIZE = 20;void main(){SeqList<int> LA(SIZE);int i = 0;for (i = 0; i<5; i++) LA.Insert(i - 1, i);LA.Insert(-1, 10);LA.Output(cout);}实现在线性表LA中插入0-4然后在一开始插入10 运行截图如下:多项式实验:定义类如下重构函数如下:源码:#include<iostream>using namespace std;class Term{public:Term(int c, int e);Term(int c, int e, Term* nxt);Term* InsertAfter(int c, int e);private:int coef;int exp;Term* link;friend ostream& operator<<(ostream &, const Term &);friend class Polynominal;};Term::Term(int c, int e) :coef(c), exp(e){link = 0;}Term::Term(int c, int e, Term *nxt) : coef(c), exp(e) {link = nxt;}Term* Term::InsertAfter(int c, int e){link = new Term(c, e, link);return link;}ostream& operator<<(ostream& out, const Term& val){if (0 == val.coef)return out;if (1!= val.coef)out<<val.coef;switch (val.exp){case 0:break;case 1:out<<"X"; break;default:out<<"X^"<<val.exp; break;}return out;}class Polynominal{public:Polynominal();~Polynominal();void AddTerms(istream& in);void Output(ostream& out)const;void PolyAdd(Polynominal& r);void PolyMul(Polynominal& r);private:Term* theList;friend ostream& operator<<(ostream &, const Polynominal &);friend istream& operator>>(istream&, Polynominal &);friend Polynominal& operator+(Polynominal &, Polynominal &);friend Polynominal& operator*(Polynominal &, Polynominal &); };Polynominal::Polynominal(){theList = new Term(0, -1); //头结点theList->link = NULL; //单链表尾结点指针域为空}Polynominal::~Polynominal(){Term* p = theList->link;while (p != NULL){theList->link = p->link;delete p;p = theList->link;}delete theList;}void Polynominal::AddTerms(istream & in){Term* q = theList;int c, e;for (;;){cout <<"Input a term(coef,exp):\n"<< endl;cin >> c >> e;q = q->InsertAfter(c, e);if (0 >= e) break;}}void Polynominal::Output(ostream& out)const{int first = 1;Term *p = theList->link;for (; p != NULL && p->exp >= 0; p = p->link){if (!first && (p->coef>0)) out<<"+";first = 0;out<< *p;}cout << endl;}void Polynominal::PolyAdd(Polynominal& r){Term *q, *q1 = theList, *p; //q1指向表头结点p = r.theList->link; //p指向第一个要处理的结点q = q1->link; //q1是q的前驱,p和q就指向两个当前进行比较的项while (p != NULL && p->exp >= 0)//对r的单循环链表遍历,知道全部结点都处理完{while (p->exp < q->exp) //跳过q->exp大的项{q1 = q;q = q->link;}if (p->exp == q->exp) //当指数相等时,系数相加{q->coef = q->coef + p->coef;if (q->coef == 0) //若相加后系数为0,则删除q{q1->link = q->link;delete(q);q = q1->link; //重置q指针}else{q1 = q; //若相加后系数不为0,则移动q1和qq = q->link;}}else//p>exp>q->exp的情况q1 = q1->InsertAfter(p->coef, p->exp); //以p的系数和指数生成新结点,插入q1后 p = p->link;}}void Polynominal::PolyMul(Polynominal& r){Polynominal result; //定义相乘后的数据Term *n = result.theList; //n指向result的头结点n = n->InsertAfter(0, 0); //在result的头结点后插入新结点,系数指数均为0 Term *p = r.theList->link; //p指向第一个要处理的结点while(p->exp >= 0) //对r的单循环链表遍历{Polynominal tmp; //存储某段相乘后的数据Term *m = tmp.theList; //m指向tmp的头结点Term *q = theList->link; //q指向表头结点的后继结点while(q->exp >= 0) //对当前对象的单循环环链表遍历{m = m->InsertAfter((p->coef)*(q->coef), (p->exp) + (q->exp)); //生成新结点插入n后 q = q->link;}result.PolyAdd(tmp); //将temp加到result上p = p->link;}Term *q = theList->link; //q指向表头结点的后继结点while(q != NULL) //删除原对象的所有数据{theList->link = q->link;delete q;q = theList->link;}q = theList;q = q->InsertAfter(0, 0);PolyAdd(result); //将result加到当前对象上}ostream &operator<<(ostream& out, const Polynominal& x){x.Output(out);return out;}istream &operator>>(istream& in, Polynominal &x){x.AddTerms(in);return in;}Polynominal & operator + (Polynominal &a, Polynominal &b){a.PolyAdd(b);return a;}Polynominal & operator * (Polynominal &a, Polynominal &b){a.PolyMul(b);return a;}int main()实验报告文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.。
实验一运算器实验

实验一运算器实验简介:运算器是数据的加工处理部件,是CPU的重要组成部分,各类计算机的运算器结构可能有所不同,但是他们的最基本的结构中必须有算术/逻辑运算单元、数据缓冲寄存器、通用寄存器、多路转换器的数据总线的逻辑构件。
一、实验目的1、了解算术逻辑运算器(74LS181)的组成和功能。
2、掌握基本算术和逻辑运算的实现方法。
二、实验内容运用算术逻辑运算器74LS181 进行有符号数/无符号数的算术运算和逻辑运算。
三、实验元器件1、算术逻辑运算器(74LS181)。
2、三态门(74LS244、74LS245)及寄存器(74LS273、74LS373)。
3、二进制拨码开关SW-SPDT四、实验原理图1.1运算器电路原理图本实验的算术逻辑运算器电路如图 1.1所示:输入和输出单元跟上述实验相同:缓冲输入区八位拨码开关用来给出参与运算的数据,并经过三态门74LS245 和数据总线BUS相连,在控制开关SW_BUS处于高电平时允许输出到数据总线。
运算器则由两个74LS181以串行进位形式构成8位字长的算术/逻辑运算单元(ALU):ALU_L4B的进位输出端CN+4与ALU_H4B的进位输入端CN相连,使低4位运算产生的进位送进高4位运算中。
其中ALU_L4B为低4位运算芯片,参与低四位数据运算,ALU_H4B为高4位运算芯片,参与高四位数据运算。
ALU_L4B的进位输入端CN通过三态门连接到二进制开关CN,控制运算器仅为,ALU_H4B的进位输出端CN+4经过反相器74LS04,通过三态门接到溢出标志位CF指示灯(CF=1,即ALU运算结果溢出)。
ALU 除了溢出标志位CF外,还有两个标志位:零标志位ZF(ZF=1,即ALU运算结果为0,ZF对应发光二极管点亮)和符号标志位SF(SF=1,即运算结果为负数;SF=0 即运算结果为正数或0对应发光二极管点亮)。
图 1.2 运算器通路图ALU 的工作方式可通过设置两个74181芯片的控制信号(S0、S1、S2、S3、M、CN)来实现, 其74LS181逻辑功能表由表1-1给出,运算器ALU 的输出经过三态门(两片74LS244或一片74LS245)和数据总线BUS 相连。
算术逻辑运算实验总结

算术逻辑运算实验总结一、引言在现代社会中,算术逻辑运算是一项基本且必不可少的能力。
它们不仅在日常生活中起着重要作用,也广泛应用于各个领域的科学和工程。
为了提高算术逻辑运算的能力,我进行了几项实验,并总结了一些重要的经验和教训。
二、实验一:基本算术运算在这个实验中,我进行了一系列的基本算术运算,如加法、减法、乘法和除法。
通过这些运算,我更加熟悉了数字和运算的关系,并且提高了我的计算速度和准确性。
通过这个实验,我发现了一些有趣的现象。
首先,我发现加法和减法是最简单的运算,因为它们只涉及到数字的简单相加或相减。
而乘法和除法则需要更多的思考和推理,因为它们涉及到数字的相对大小和关系。
除此之外,在进行算术运算时,我还体会到了一些技巧和方法。
例如,在进行长数列的相加时,可以将它们分成多个小段,然后分别相加,最后再将结果相加。
这样可以降低错误的可能性,同时提高计算的效率。
三、实验二:逻辑运算逻辑运算是另一种重要的运算方式。
在这个实验中,我学习了逻辑运算的基本原理和方法,并进行了一些实际的应用。
首先,我学习了与运算、或运算和非运算的基本规则。
通过这些规则,我可以判断一个命题的真假,或者从若干个命题中得出一个新的结论。
这是在科学和工程中经常用到的一种思维方式。
其次,我了解了逻辑运算在算法设计和编程中的重要性。
在编写程序时,逻辑运算用于判断条件和控制程序的流程。
通过合理地使用逻辑运算,可以使程序更加高效和精确。
实验中,我发现了一些常见的逻辑谬误。
例如,德摩根定律的错误应用会导致逻辑矛盾和错误的结果。
因此,在进行逻辑运算时,我要特别注意各种规则和定律的正确使用。
四、实验三:复杂算术逻辑运算在这个实验中,我尝试了一些更加复杂的算术逻辑运算,如平方根运算、对数运算和三角函数运算。
通过这些运算,我更深入地了解了数学的奥秘和复杂性。
在进行这些运算时,我遇到了一些困难和挑战。
首先,一些运算需要使用特殊的方法和技巧,我要仔细学习和掌握这些技术。
dsp 基本算数运算

实验一:基本算数运算1 、实验目的和要求加、减、乘、除是数字信号处理中最基本的算术运算。
本实验学习使用定点DSP 实现16 位定点加、减、乘、除运算的基本方法和编程技巧。
本实验的演示文件为exer1.out。
2 、实验原理1) 定点DSP 中的数据表示方法在DSP 中一个16 进制的数可以表示不同的十进制数,或者是整数,或者是小数(如果表示小数,必定小于1),但仅仅是在做整数乘除或小数乘除时,系统对它们的处理才是有所区别的,而在加减运算时,系统都当成整数来处理。
2) 实现16 位定点加法在本实验中,我们使用下列代码来说明加法运算:ld temp1,a ;将变量temp1 装入寄存器Aadd temp2,a ;将变量temp2 与寄存器A 相加,结果放入A 中stl a,add_result ;将结果(低16 位)存入变量add_result 中。
注意,这里完成计算temp3=temp1+temp2,我们没有特意考虑temp1 和temp2 是整数还是小数,在加法和下面的减法中整数运算和定点的小数运算都是一样的。
3) 实现16 位定点减法在本实验中,我们使用下列代码来说明减法运算:stm #temp1,ar3 ;将变量temp1 的地址装入ar3 寄存器stm #temp3,ar2 ;将变量temp3 的地址装入ar2 寄存器sub *ar2+, *ar3,b ;将变量temp3 左移16 位同时变量temp1 也左移16 位,然后;相减,结果放入寄存器B(高16 位)中,同时ar2 加1。
sth b,sub_result ;将相减的结果(高16 位)存入变量sub_result。
4) 实现16 位定点整数乘法在本实验中,我们使用下列代码来说明整数乘法运算:rsbx FRCT ;清FRCT 标志,准备整数乘ld temp1,T ;将变量temp1 装入T 寄存器mpy temp2,a ;完成temp2*temp1,结果放入A 寄存器(32 位)例如,当temp1=1234H(十进制的4660),temp2=9876H(十进制的-26506),乘法的结果在A 寄存器中为0F8A343F8H(十进制的-123517960)。
基本运算器实验

计算机科学与技术系实验报告专业名称_______ 计算机科学与技术_________课程名称________ 计算机组成原理__________项目名称________ 基本运算器实验__________班级_______________________________学号_______________________________姓名_______________________________同组人员_________________________________实验日期_________________________________一、实验目的与要求实验目的(1)了解运算器的组成结构(2)掌握运算器的工作原理实验要求(1)实验之前,应认真准备,写出实验步骤和具体设计内容,否则实验效率会很低, 次实验时间根本无法完成实验任务;(2)应在实验前掌握所以控制信号的作用,写出实验预习报告并带入实验室;(3)实验过程中,应认真进行实验操作,既不要因为粗心造成短路等事故而损坏设备,又要自习思考实验有关内容;(4)实验之后,应认真思考总结,写出实验报告,包括实验步骤和具体实验结果,遇到的问题和分析与解决思路。
还应写出自己的心得体会,也可以对教学实验提出新的建议等。
实验报告要上交老师。
二、实验逻辑原理图与分析画实验逻辑原理图逻辑原理图分析上图为运算器原理图。
如图所示运算器内部含有三个独立运算部件,分别为算术、逻辑和移位运算部件,要处理的数据存于暂存器A和暂存器B,三个部件同时接受来自A 和B的数据(有些处理器体系结构把移位运算器放于算术和逻辑运算部件之前,如ARM,各部件对操作数进行何种运算由控制信号S3- S0和CN来决定(三选一开关),任何时候,多路选择开关只选择三部件中一个部件的结果作为ALU的输出。
如果是影响进位的运算,还将置进位标志FC,在运算结果输出前,置ALU零标志FZ。
ALU中所有模块集成在一片CPLD中。
算术运算类实验报告
一、实验目的1. 熟悉并掌握基本的算术运算算法。
2. 理解算术运算在编程中的应用。
3. 培养学生的逻辑思维能力和编程能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容本次实验主要涉及以下算术运算:加法、减法、乘法、除法、求余、幂运算等。
1. 加法运算加法运算是指将两个数相加得到它们的和。
以下是一个加法运算的示例代码:```pythondef add(a, b):return a + bresult = add(3, 5)print("加法运算结果:", result)```2. 减法运算减法运算是指将一个数从另一个数中减去得到它们的差。
以下是一个减法运算的示例代码:```pythondef subtract(a, b):return a - bresult = subtract(10, 4)print("减法运算结果:", result)```3. 乘法运算乘法运算是指将两个数相乘得到它们的积。
以下是一个乘法运算的示例代码:```pythondef multiply(a, b):return a bresult = multiply(2, 6)print("乘法运算结果:", result)```4. 除法运算除法运算是指将一个数除以另一个数得到它们的商。
以下是一个除法运算的示例代码:```pythondef divide(a, b):return a / bresult = divide(10, 2)print("除法运算结果:", result)```5. 求余运算求余运算是指将一个数除以另一个数得到它们的余数。
以下是一个求余运算的示例代码:```pythondef mod(a, b):return a % bresult = mod(10, 3)print("求余运算结果:", result)```6. 幂运算幂运算是指将一个数自乘多次得到它的幂。
计算机组成原理 运算器实验—算术逻辑运算实验
实验报告一、实验名称运算器实验—算术逻辑运算实验二、实验目得1、了解运算器得组成原理。
2、掌握运算器得工作原理.3、掌握简单运算器得数据传送通路。
4、验证运算功能发生器(74LS181)得组合功能.三、实验设备TDN-CM++计算机组成原理教学实验系统一套,导线若干。
四、实验原理实验中所用得运算器数据通路如图1-1所示。
其中两片74LSl81以串行方式构成8位字长得ALU,ALU得输出经过一个三态门(74LS245)与数据总线相连.三态门由ALU—R控制,控制运算器运算得结果能否送往总线,低电平有效。
为实现双操作数得运算,ALU得两个数据输入端分别由二个锁存器DR1、DR2(由74LS273实现)锁存数据。
要将数据总线上得数据锁存到DRl、DR2中,锁存器得控制端LDDR1与DDR2必须为高电平,同时由T4脉冲到来。
数据开关(“INPUTDEVICE”)用来给出参与运算得数据,经过三态(74LS245)后送入数据总线,三态门由SW—B控制,低电平有效。
数据显示灯(“B USUNIT")已与数据总线相连,用来显示数据总线上得内容.图中已将用户需要连接得控制信号用圆圈标明(其她实验相同,不再说明),其中除T4为脉冲信号外,其它均为电平信号。
由于实验电路中得时序信号均已连至“W/RUNIT”得相应时序信号引出端,因此,在进行实验时,只需将“W/R UNIT"得T4接至“STATE UNIT"得微动开关KK2得输入端,按动微动开关,即可获得实验所需得单脉冲.ALU运算所需得电平控制信号S3、S2、S1、S0、Cn、M、LDDRl、LDDR2、ALU-B、SW-B均由“SWITCH UNIT ”中得二进制数据开关来模拟,其中Cn、ALU—B、SW一B为低电平有效LDDR1、LDDR2为高电平有效。
对单总线数据通路,需要分时共享总线,每一时刻只能由一组数据送往总线。
五、实验内容1.输入数据通过三态门74LS245后送往数据总线,在数据显示灯与数码显示管LED上显示。
实验一 8位算术逻辑运算实验
实验一8位算术逻辑运算实验一、实验目的1、掌握简单运算器的数据传送通路组成原理。
2、验证算术逻辑运算功能发生器74L S181的组合功能。
二、实验内容1、实验原理实验中所用的运算器数据通路如图3-1所示。
其中运算器由两片74L S181以并/串形成8位字长的A L U构成。
运算器的输出经过一个三态门74L S245(U33)到内部数据总线B U S D0~D7插座B U S1~2中的任一个(跳线器J A3为高阻时为不接通),内部数据总线通过L Z D0~L Z D7显示灯显示;运算器的两个数据输入端分别由二个锁存器74L S273(U29、U30)锁存,两个锁存器的输入并联后连至内部总线B U S,实验时通过8芯排线连至外部数据总线E X D0~D7插座E X J1~E X J3中的任一个;参与运算的数据来自于8位数据开并K D0~K D7,并经过一三态门74L S245(U51)直接连至外部数据总线E X D0~E X D7,通过数据开关输入的数据由L D0~L D7显示。
图中算术逻辑运算功能发生器74L S181(U31、U32)的功能控制信号S3、S2、S1、S0、C N、M并行相连后连至6位功能开关,以手动方式用二进制开关S3、S2、S1、S0、C N、M来模拟74L S181(U31、U32)的功能控制信号S3、S2、S1、S0、C N、M;其它电平控制信号L D D R1、L D D R2、A L U B`、S W B`以手动方式用二进制开关L D D R1、L D D R2、A L U B、S W B来模拟,这几个信号有自动和手动两种方式产生,通过跳线器切换,其中A L U B`、S W B`为低电平有效,L D D R1、L D D R2为高电平有效。
另有信号T4为脉冲信号,在手动方式下进行实验时,只需将跳线器J23上T4与手动脉冲发生开关的输出端S D相连,按动手动脉冲开关,即可获得实验所需的单脉冲。
(计算机组成原理)实验一运算器实验
D
红色:运算器控制信号
BUS UNIT
蓝色:器件中信号
运算器电路图
M
S3
当为减
S2
法算术
S1
运算时
S0
输出1
ALU TO BUS
D7-D0
ALU-B
B7 B6 B5 B4 B3 B2 B1 B0 +5
A7
A6
A74LS2455
A4
A3
A2
A1
DIR E
A0
+5 +5
ZI D SET Q
1K
Q
CLR
Ci
返回
CN+4 F3 F2 F1 F0
S3
S2
ALU(74LS181)
S1 S0
M
CN
A3 A2 A1 A0 B3 B2 B1 B0
F3 F2 F1 F0
S3
S2
ALU(74LS181)
S1 S0
M
CN+4
A3 A2 A1 A0 B3 B2 B1 B0CN
S3 S2 S1 S0 M
Cn181
DA1,DA2:两片74LS273
T4 T1 B-IR
I3-I0
寄存器 译码
B-R0
MA6 -MA0
B-R1 B-R2
B-R3
R0-B
R1-B
R2-B
MA6-MA0
R3-B
D6-D0
J1
I7-I2
T1 微地址锁存器 OE CLK Q6-Q0 CLR
|
J5
FZ
指令译码器
FC
INT
T4 KA
7
KB
Q6-Q0
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实基本算术运算1. 实验目的加、减、乘、除是数字信号处理中最基本的算术运算。
DSP中提供了大量的指令来实现这些功能。
本实验学习使用定点DSP实现16位定点加、减、乘、除运算的基本方法和变成技巧。
2. 实验原理(1)定点DSP中数据表示方法C54X是16位的定点DSP。
一个16位的二进制数既可以表示一个整数,也可以表示一个小数。
当它表示一个整数时,其最低位(D0)表示20,D1位表示21,次高位(D14)表示214。
如果表示一个有符号数时,最高位(D15)为符号位,0表示正数,1表示负数。
例如,07FFFH表示最大的正数32767(十进制),而0FFFFH表示最大的负数-1(负数用2的补码方式显示)。
当需要表示小数时,小数点的位置始终在最高位后,而最高位(D15)表示符号位。
这样次高位(D14)表示2-1,然后是2-2,最低位(D0)表示2-15。
所以04000H表示小数0.5,01000H 表示小数2-3=0.125,而0001H表示16位定点DSP能表示的最小的小数(有符号)2-15=0.000030517578125。
在后面的实验中,除非有特别说明,我们指的都是有符号数。
在C54X中,将一个小数用16位定点格式来表示的方法是用215乘以该小数,然后取整。
从上面的分析可以看出,在DSP中一个16进制的数可以表示不同的十进制数,或者是整数,或者是小数(如果表示小数,必定小于1),但仅仅是在做整数乘除或小数乘除时,系统对它们的处理才是有所区别的,而在加减运算时,系统都当成整数来处理。
(2)实现16定点加法C54X中提供了多条用于加法的指令,如ADD,ADDC,ADDM和ADDS。
其中ADDS 用于无符号数的加法运算,ADDC用于带进位的加法运算(如32位扩展精度加法),而ADDM专用于立即数的加法。
(3)实现16位定点减法C54X中提供了多条用于减法的指令,如SUB,SUBB,SUBC和SUBS。
其中SUBS用于无符号数的减法运算,SUBB用于带进位的减法运算(如32位扩展精度的减法),而SUBC为移位减,DSP中的除法就是用该指令来实现的。
(4)实现16定点整数乘法在C54X中提供了大量的乘法运算指令,其结果都是32位,放在A或B寄存器中。
乘数在C54X的乘法指令很灵活,可以是T寄存器、立即数、存贮单元和A或B寄存器的高16位。
在C54X中,一般对数据的处理都当做有符号数,如果是无符号数乘时,请使用MPYU指令。
这是一条专用于无符号数乘法运算的指令,而其它指令都是有符号数的乘法。
(5)实现16定点小数乘法在C54X中,小数的乘法与整数乘法基本一致,只是由于两个有符号的小数相乘,其结果的小数点的位置在次高的后面,所以必须左移一位,才能得到正确的结果。
C54X中提供了一个状态位FRCT,将其设置为1时,系统自动将乘积结果左移一位。
但注意整数乘法时不能这样处理,所以上面的实验一开始便将FRCT清除。
两个小数(16位)相乘后结果为32位,如果精度允许的话,可以只存高16位,将低16位丢弃,这样仍可得到16位的结果。
(6)实现16定点整数除法在C54X中没有提供专门的除法指令,一般有两种方法来完成除法。
一种是用乘法来代替,除以某个数相当于乘以其倒数,所以先求出其倒数,然后相乘。
这种方法对于除以常数特别适用。
另一种方法是使用SUBC指令,重复16次减法完成除法运算。
以temp1/temp2为例,其中变量temp1为被除数,temp2为除数,结果即商存放在变量temp3中。
在完成整数除法时,先判断结果的符号。
方法是将两数相乘,保存A或B的高16位以便判断结果的符号。
然后只做两个正数的除法,最后修正结果的符号。
为了实现两个数相除,先将被除数装入A或B的低16位,接着重复执行SUBC指令,用除数重复减16次后,除法运算的商在累加器的低16位,余数在高16位。
(7)实现16定点小数除法在C54X中实现16位的小数除法与前面的整数除法基本一致,也是使用循环的SUBC指令来完成。
但有两点需要注意:第一,小数除法的结果一定是小数(小于1),所以被除数一定小于除数。
这与整数除法正好相反。
所以在执行SUBC 指令前,应将被除数装入A或B寄存器的高16位,而不是低16位。
其结果的格式与整数除法一样,A或B寄存器的高16位为余数,低16位为商。
第二,与小数乘法一样,应考虑符号位对结果小数点的影响。
所以应对商右移一位,得到正确的有符号数。
3.实验内容本实验需要使用C54X汇编语言实现加、减、乘、除的基本运算,并通过DES的存贮器显示窗口观察结果。
实验分两步完成:(1)编写实验程序代码本实验的汇编源程序代码主要分为六个部分:加法、减法、整数乘法、小数乘法、整数除法和小数除法。
每个部分后面都有一条需要加断点的标志语句:nop当执行到这条加了断点的语句时,程序将自动暂停。
这时你可以通过“存贮器窗口”检查计算结果。
当然你看到的结果都是十六进制的数。
(2)在simulator上调试运行,并观察结果在完成实验程序代码的输入,并使用汇编批处理ASM.BAT进行编译连接后,就可以在simulator上调试运行。
步骤如下:a.启动simulator实验系统软件sim54X.exe。
b.在调试界面的左下脚命令栏输入load exer1.out,或单击菜单栏下面的“load”选项,并在弹出的File Name对话框中键入exer1.out装入基本算术运算实验程序,这时应能在“反汇编”窗口看到程序代码。
c.用鼠标选中“Memory”窗口,并在其中选择要查看的存贮器地址段:0x080-0x8e。
d.在反汇编窗口中在每个“nop”指令处都设一个断点,方法有两种:1.用鼠标单击该指令将其点亮即可。
2.在菜单栏中选择“Break”->“Add”,然后在弹出的对话框中键入欲加断点的地址即可。
e.单击菜单栏下的“Run=F5”按钮,启动执行基本算术运算程序,程序在执行完加法运算后自动暂停。
通过“CPU”窗口可以看到寄存器AHL的内容为0x46,这正是加法运算的结果。
同样,在“Memory”窗口中,可以看到0x81,0x82,0x88的内容分别为0012,0034,0046。
执行加法运算后,将0x81和0x82的内容相加,结果放在0x88单元。
f.在“Memory”窗口中用鼠标左键双击0x81单元,这时可以修改该内存单元的内容。
输入新的数据0x0ffee(十进制的-18),编辑内容时请直接输入FFEE (十六进制),然后回车确认,便完成对0x81单元的修改。
g.在“CPU”窗口中修改PC值,方法也是鼠标左键双击PC寄存器的内容,输入新的PC值0x0085(编辑内容时直接输入0085),并用回车键确认。
h.单击菜单栏下的“Run=F5”按钮,程序从当前PC继续运行,重新计算0x81和0x82的和,结果在0x88中。
当程序再次暂停时,可以看到AHL寄存器和0x88的内容为0x22(十进制的34),这正是我们希望的结果:-18+52=34。
i.单击“Run=F5”按钮,程序从当前PC继续运行,完成减法运算。
当程序再次暂停时(断点位于0x1813),可以看到0x83和0x84单元的内容分别为FFEE 和0012,B寄存器的内容为ffdc0000,而0x89的内容为ffdc(十进制-36),这正是我们希望的结果:-18-18=-36。
注意,该减法操作使用了辅助寄存器寻址,所以计算结果在B寄存器的高16位。
j.单击“Run=F5”按钮,程序从当前PC继续运行,完成整数乘法运算。
当程序再次暂停时(断点位于0x181d),可以看到0x81和0x82单元的内容分别为0012和0034,A寄存器的内容为000003A8,这正是我们希望的结果:18*52=936(0x3a8)。
这时我们可以用1个16位的内容单元来保存结果,如将A寄存器的低16位存入0x8b单元。
但如果将0x81的内容修改为0x2000(十进制的8192),在“CPU窗口”中将PC修改为1818,然后继续运行,重新计算乘法。
当程序完成乘法暂停时,可以看到A寄存器的内容为00068000,这也是一个正确的结果:8192*52=425984(0x68000)。
此时将无法用一个16位的存贮单元来保存A寄存器中的结果。
k.单击“Run=F5”按钮,程序从当前PC继续运行,完成小数乘法运算。
当程序再次暂停时(断点位于0x1826),可以看到0x83和0x84单元的内容分别为4000和b548,A寄存器的内容为40000000,乘法的结果在B寄存器中为daa40000,这正是我们希望的结果:0.5*(-0.58374)=-0.29187(0x0daa4)。
对于小数乘法,一般情况都可以用1个16位的内容单元将B寄存器的高16位保存(如存入0x8c)单元。
l.单击“Run=F5”按钮,程序从当前PC继续运行,完成整数除法运算。
当程序再次暂停时(断点位于0x183b),可以看到0x81,0x82,0x8d和0x8e单元的内容分别为0034,0012,FFEE和0010,这正是我们希望的结果:52除以-18,商为-2(0xfffe),余数为16(0x10)。
m.单击“Run=F5”按钮,程序从当前PC继续运行,完成小数除法运算。
当程序再次暂停时(断点位于0x1852),可以看到0x81,0x82和0x8f单元的内容分别为4000,4ab8和6da3,这正是我们希望的结果:0.5/0.58374=0.8565457(0x6da3)n.如果以上程序运行不正确,请检查代码是否输入正确,还可以在源代码中插入断点调试,注意对中间结果的观察。
4.思考题(1)在减法操作中使用了辅助寄存器ar2,ar3,请说明在执行完减法计算后辅助寄存器ar2和ar3的值为多少?(2)在小数乘法中使用了置FRCT标志为1的指令。
如果将该语句取消,那么B寄存器的结果是多少?想想什么时候应该设置FRCT标志?(3)如何实现无符号数的乘法?(4)请利用本实验程序计算以下算式的结果0.25*0.58374=?0.5/0.25=?4653/345=?0.789687/0.876=?。