【计算机组成与体系结构Ⅰ】课后作业汇总

news2024/11/13 10:59:21

目录

1-1

1-2

2-1

3-1

3-2

4-1

4-2

5-1

6-1

6-2

7-1

7-2


1-1

作业1. 袁春风《计算机组成与系统结构》第2版或者第3版:第1章 习题 2(1)-(3)

  1. 冯·诺依曼计算机由哪几部分组成?各部分的功能是什么?采用什么工作方式?

答:

运算器、控制器、存储器、输入设备、输出设备五大基本部件组成。

各部分在功能上表现为:运算器:用于完成各种算术运算、逻辑运算和数据传送等数据加工处理。控制器:用于控制程序的执行,是计算机的大脑。运算器和控制器组成计算机的中央处理器(CPU)。控制器根据存放在存储器中的指令序列(程序)进行工作,并由一个程序计数器控制指令的执行。控制器具有判断能力,能根据计算结果选择不同的工作流程。存储器:用于记忆程序和数据,例如:内存。程序和数据以二进制代码形式不加区别地存放在存储器中,存放位置由地址确定。输入设备:用于将数据或程序输入到计算机中,如鼠标、键盘等。输出设备:将数据或程序的处理结果展示给用户,如显示器、打印机等。

各部分在工作方式上表现为:不同部件之间通过指令进行控制和数据传递的行为。

  1. 摩尔定律的主要内容是什么?

答:

摩尔定律是英特尔创始人之一戈登·摩尔的经验之谈,其核心内容为:集成电路上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍。换言之,处理器的性能大约每两年翻一倍,同时价格下降为之前的一半。

  1. 计算机系统的层次结构如何划分?计算机系统的用户可分为哪几类?每类用户工作在哪个层次?

答:

计算机系统的层次结构可划分为:硬件 + 软件。硬件部分包括CPU、主存和输入输出设备等主要功能部件。软件部分包括底层的系统软件和高层的应用软件,汇编程序、编译程序和操作系统等这些系统软件直接在ISA上实现。

计算机系统的用户可划分为:最终用户、系统管理员、应用管理员、系统程序员。

工作层次为:最终用户和应用程序员工作在应用程序层次;系统程序员工作在ISA层次;系统管理员同时工作在应用程序层次和ISA层次。

作业 2. 在linux环境下(或者Cygwin下),用GCC  对 教材1.4.1 中 hello.c 分别实现预处理、编译、汇编、链接。(1)简单说明预处理、编译、汇编、链接的作用;(2)并用 objdump -d hello.o  将显示内容与hello.s对比。

(1)各部分阶段的作用如下所示

预处理:预处理程序(cpp)对源程序中以字符#开头的命令进行处理。其输出结果还是一个源程序文件,以i为扩展名。

编译:编译程序(ccl)对预处理后的源程序进行编译,生成一个汇编语言源程序文件,以s为扩展名。

汇编:汇编程序(as)对汇编语言源程序进行汇编,生成一个可重定位目标文件,以o为扩展名。它是一种二进制文件,因为其中的代码已经是机器指令,数据以及其他信息均用二进制表示,所以它不可读,即打开显示出来的是乱码。

链接:链接程序(ld)将多个可重定位目标文件和标准库函数合并成为一个可执行目标文件(简称为可执行文件)。最终生成的可执行文件被保存在磁盘上,可以通过某种方式启动一个磁盘上的可执行文件运行。

(2)显示内容对比如下所示


objdump -d hello.o:Objdump,指反汇编。把目标代码转为汇编代码的过程,即把机器语言转换为汇编语言代码、是低级转高级的一种指令。

 

hello.o:     file format pe-x86-64


Disassembly of section .text:

0000000000000000 <printf>:
   0:   55                      push   %rbp
   1:   53                      push   %rbx
   2:   48 83 ec 38             sub    $0x38,%rsp
   6:   48 8d 6c 24 30          lea    0x30(%rsp),%rbp
   b:   48 89 4d 20             mov    %rcx,0x20(%rbp)
   f:   48 89 55 28             mov    %rdx,0x28(%rbp)
  13:   4c 89 45 30             mov    %r8,0x30(%rbp)
  17:   4c 89 4d 38             mov    %r9,0x38(%rbp)
  1b:   48 8d 45 28             lea    0x28(%rbp),%rax
  1f:   48 89 45 f0             mov    %rax,-0x10(%rbp)
  23:   48 8b 5d f0             mov    -0x10(%rbp),%rbx
  27:   b9 01 00 00 00          mov    $0x1,%ecx
  2c:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # 33 <printf+0x33>
  33:   ff d0                   call   *%rax
  35:   48 89 c1                mov    %rax,%rcx
  38:   48 8b 45 20             mov    0x20(%rbp),%rax
  3c:   49 89 d8                mov    %rbx,%r8
  3f:   48 89 c2                mov    %rax,%rdx
  42:   e8 00 00 00 00          call   47 <printf+0x47>
  47:   89 45 fc                mov    %eax,-0x4(%rbp)
  4a:   8b 45 fc                mov    -0x4(%rbp),%eax
  4d:   48 83 c4 38             add    $0x38,%rsp
  51:   5b                      pop    %rbx
  52:   5d                      pop    %rbp
  53:   c3                      ret

0000000000000054 <main>:
  54:   55                      push   %rbp
  55:   48 89 e5                mov    %rsp,%rbp
  58:   48 83 ec 20             sub    $0x20,%rsp
  5c:   e8 00 00 00 00          call   61 <main+0xd>
  61:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # 68 <main+0x14>
  68:   48 89 c1                mov    %rax,%rcx
  6b:   e8 90 ff ff ff          call   0 <printf>
  70:   b8 00 00 00 00          mov    $0x0,%eax
  75:   48 83 c4 20             add    $0x20,%rsp
  79:   5d                      pop    %rbp
  7a:   c3                      ret
  7b:   90                      nop
  7c:   90                      nop
  7d:   90                      nop
  7e:   90                      nop
  7f:   90                      nop


hello.s:

 

.file	"hello.c"
	.text
	.def	printf;	.scl	3;	.type	32;	.endef
	.seh_proc	printf
printf:
	pushq	%rbp
	.seh_pushreg	%rbp
	pushq	%rbx
	.seh_pushreg	%rbx
	subq	$56, %rsp
	.seh_stackalloc	56
	leaq	48(%rsp), %rbp
	.seh_setframe	%rbp, 48
	.seh_endprologue
	movq	%rcx, 32(%rbp)
	movq	%rdx, 40(%rbp)
	movq	%r8, 48(%rbp)
	movq	%r9, 56(%rbp)
	leaq	40(%rbp), %rax
	movq	%rax, -16(%rbp)
	movq	-16(%rbp), %rbx
	movl	$1, %ecx
	movq	__imp___acrt_iob_func(%rip), %rax
	call	*%rax
	movq	%rax, %rcx
	movq	32(%rbp), %rax
	movq	%rbx, %r8
	movq	%rax, %rdx
	call	__mingw_vfprintf
	movl	%eax, -4(%rbp)
	movl	-4(%rbp), %eax
	addq	$56, %rsp
	popq	%rbx
	popq	%rbp
	ret
	.seh_endproc
	.def	__main;	.scl	2;	.type	32;	.endef
	.section .rdata,"dr"
.LC0:
	.ascii "hello\243\254world!\12\0"
	.text
	.globl	main
	.def	main;	.scl	2;	.type	32;	.endef
	.seh_proc	main
main:
	pushq	%rbp
	.seh_pushreg	%rbp
	movq	%rsp, %rbp
	.seh_setframe	%rbp, 0
	subq	$32, %rsp
	.seh_stackalloc	32
	.seh_endprologue
	call	__main
	leaq	.LC0(%rip), %rax
	movq	%rax, %rcx
	call	printf
	movl	$0, %eax
	addq	$32, %rsp
	popq	%rbp
	ret
	.seh_endproc
	.ident	"GCC: (GNU) 12.2.0"
	.def	__mingw_vfprintf;	.scl	2;	.type	32;	.endef

(3)其他过程截图

1:在unix终端使用gcc驱动

预处理: gcc -E project.c -o project.i

编译: gcc -S project.i -o project.s

汇编: gcc -c project.S -o project.o

链接: gcc project.o  -o project

预处理

生成预处理文件 project.i
宏展开 包含展开

编译

生成汇编文件 project.S
高级语言转成低级语言

汇编

生成机器语言 project.o
生成未地址定位的机器码

链接

生成可运行程序project
加载库文件

2:根目录下生成的文件信息

文件从上至下依次为:Hello.c、Hello.exe、Hello.i、Hello.o、Hello.s


1-2

作业1. 袁春风《计算机组成与系统结构》(第2版或者第3版) 第1章:习题 5 , 6

习题5:

 

  1. 对于P1,M2快,比M1快1倍。对于P2,M1快,比M2快1倍。
  2. 对于M1,P1的速度为200M/10=20MIPS,P2的速度为0.3M/0.003=100MIPS。
    对于M2, P1的速度为150M/5=30MIPS,P2的速度为0.42M/0.006=70MIPS。从执行速度来看,对于P2,M1更快,快10/7倍。
  3. 执行P1时的平均时钟周期数,M1为10*800M/(200*10^6)=40,M2为5*1.2G/(150*10^6)=40。
  4. 对于P1主要关心响应时间,即执行时间越短且价格越低,性价比越好。对于M1,10*5000=50000,对于M2,5*8000=40000。
    因此应该选择M2,因为M2的执行时间*价格更小,性价比更高。
  5. 采用算数平均方式计算时,对于M1性价比为(10+0.003)/2*5000=25007.5,对于M2性价比为(5+0.006)/2*8000=20024。
    因此应该选择M2,因为M2的执行时间*价格的算术平均值更小,性价比更高。
    采用几何平均方式计算时,对于M1性价比为sqrt(10*0.003)*5000=886.03,对于M2性价比为sqrt(5*0.006)*8000=1385.64。
    因此应该选择M1,因为M1的执行时间*价格的几何平均值更小,性价比更高。

 习题6:

  1. MIPS=f/(CPI*10^6),峰值MIP要求CPI为最小值。
    所以M1的峰值MIPS为1000/1=1000MIPS,M2的峰值MIPS为1500/2=750MIPS。
  2. 五类指令占比均为0.2,M1上的平均CPI为0.2*(1+2+2+3+4)=2.4,M2上的平均CPI为0.2*(2+2+4+5+6)=3.8
    令总指令条数为N,则M1上的执行时间为2.4*N*1/1G=2.4N(ns),M2上的执行时间为3.8*N*1/1.5G=2.53N(ns)
    所以M1更快,比M2快(2.53-2.4)/2.53=0.05倍。

2-1

1、一个C语言程序运行在32位计算机上,程序中有如下变量:s , x,z为 int类型,y为short类型,x=127,y=-9 ,执行x=x+y, s=x,z=y, 在计算机中s,z的机器码表示? 

A s补=0076H,z补=0000FFF7H 

B s补=00000076H,z补=FFFFFFF7H 

C s补=00000076H,z补=FFF7H

D s补=00000076H,z补=8009H

过程:

执行x=x+y时,计算后的x仍然为int类型;

执行s=x时,赋值后的s为int类型,大小为118;

执行z=y时,赋值后的z为short类型,大小为-9;

所以s的原码为0000 0000 0000 0000 0000 0000 0111 0110

同时z的原码为1000 0000 0000 1001

所以s的补码(正数与原码相同)为0 0 0 0 0 0 7 6 H

同时z的补码(负数为原码取反加一,反码为1111 1111 1111 0110)为F F F 7 H


2、教材(袁春风,《计算机组成与系统结构》第2版)p64,写出12 题中-1/8的IEEE754单精度浮点格式。

-1/8=-0.125=-1.0*2^(-3)

阶码为-3+127=124=01111100B

数符为1,尾数为1.0…0

单精度浮点格式为:1 01111100 000 0000 0000 0000 0000 0000

即BE000000H

 3、有以下变量:x为float型,y为int型,s为 short,请用C语言程序实现:可输入对应的变量值,输出其在内存中存储的每个字节的内容。比如,x=-12.5, 输出对应存储4字节内容及每个字节对应的地址。源程序和运行结果截图

源程序:

#include <cstdio>

int main(){
	float x;
	int y;
	short s;
	char *c1,*c2,*c3;

	printf("请输入x,y,z的值,以空格分开:\n");
	scanf("%f %d %d",&x,&y,&s);
	c1=(char*)&x;
	c2=(char*)&y;
	c3=(char*)&s;
	//c=(char*)&x;
	//先取x的首地址,然后强制转换为char指针类型。
	//本质上还是把x的地址给c,只不过现在的类型是char而不是int。
	
	//x output
	printf("x在内存中存储的每个字节的内容及其地址为:\n");
	for(int i=0;i<sizeof(x);i++){
		printf("%x \t %x \n",(c1+i),*(c1+i));
	}
	//y output
	printf("y在内存中存储的每个字节的内容及其地址为:\n");
	for(int i=0;i<sizeof(y);i++){
		printf("%x \t %x \n",(c2+i),*(c2+i));
	}
	//z output
	printf("s在内存中存储的每个字节的内容及其地址为:\n");
	for(int i=0;i<sizeof(s);i++){
		printf("%x \t %x \n",(c3+i),*(c3+i));
	}
	//(c+i)输出的是地址。
	//*(c+i)输出的是该地址所存储的数。
	return 0;
}

运行结果截图:

(此处以x=-12.5,y=-12,z=-12为例)


3-1


1:第2版教材: p.105 7 (1) , 或者 第3版 教材:p89  7(1)

(1)

[x+y]补=[x]补+[y]补

[x]补=[x]原=001010

[y]原=100110,所以[y]补=111010

所以[x+y]补=001010+111010=000100

[x-y]补=[x]补+[-y]补

-y=6,所以[-y]补=[-y]原=000110

所以[x-y]补=[x]补+[-y]补=001010+000110=010000

综上所述:[x+y]补=000100(B)=4,[x-y]补=010000(B)=16。


2:根据第2版书中p79页算法和图3.10的结构,或者第3版书中p63页算法和图3-10结构,完成以下内容:

每一步迭代过程:

  1. 取乘数的最低位Yn-i判断。
  2. 若Yn-i的值为1,则将上一步迭代部分积Pi与X相加;若Yn-i的值为0,则什么也不做。
  3. 右移一位,产生本次部分积Pi+1

用C语言编写程序模拟"原码1位乘法运算",并输出被乘数寄存器、乘数寄存器Y、乘积寄存器P在每一步迭代计算过程中的值,以二进制或者16进制显示。提交源代码和运行结果截图。

源代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

unsigned long long int multiply(unsigned long long int x, unsigned long long int y){
    unsigned long long int result,i;
    char sx[32],sy[32],s[32];
	//模拟寄存器 
    result = 0;
    
    int tx = (int)x,ty = (int)y,ts;
    itoa(tx, sx, 2);
    itoa(ty, sy, 2);
	//转二进制写入数组
    unsigned len = strlen(sy);
    //限制循环次数
	 
    printf("\t\t\t\tX \t\t\t\tY \t\t\t\tP\n");
    printf("%32s %32s\n", sx, sy);
    
    for(i=0;i<len;i++){
        if((y&1) == 1){
            result += x;
        }
        x = x << 1;
        y = y >> 1;
        tx = (int)x;
        ty = (int)y;
        ts = (int)result;
        itoa(tx, sx, 2);
        itoa(ty, sy, 2);
        itoa(ts, s, 2);
        printf("%32s %32s %32s\n", sx, sy,s);
    }
    return result; 
}

int main(){
	unsigned long long int x=9,y=9,r;
    char sx[32]; 
    r = multiply(x,y);
    int t = (int)r;
    itoa(t,sx,2);
    printf("Binary结果为:%s B\n",sx);
    printf("Decimal结果为:%d D\n",r);
	return 0;
}


运行结果截图:(以x=9,y=9为例)

 


3-2

请完成第2版教材p105-106页 9,10题,或者第3版教材p89页9,10题

9:在IEEE754浮点数运算中,当结果的尾数出现什么形式时需要进行左规,出现什么形式时需要进行右规?如何进行左规,如何进行右规?

答:

(1)当结果为±0.00…01xx…xx的时候,需要进行左规。

采取左规时,数值位需要逐次左移,阶码需要逐次减1,直至第一个非0数的位置刚好在小数点左边。

尾数左移时,数值部分最左k个0被移出,所以相对而言,小数点右移了k位并移到了隐藏位“1”的后面,执行过程中一共减了k次。

(2)当结果为±1xx…xx.xx…x的时候,需要进行右规。

采取右规时,尾数需要右移1位,阶码需要加1。

尾数右移时,最高位“1”被移到小数点前以为作为隐藏位,最后一位移出时需要考虑四舍五入,且当阶码加1时直接在末尾加1。

10:在IEEE754浮点数运算中,如何判断浮点运算的结果是否溢出?

答:

通过判断阶码是否溢出,而不以尾数是否溢出作为标准,因为尾数溢出时可以通过右规进行纠正。

当阶码上溢时,说明结果的数值太大,无法表示。

当阶码下溢时,说明结果数值太小,可以使结果近似为0。

在对数值进行运算的过程中,通常需要队阶码进行加减运算,可能会发生阶码上溢或阶码下溢,所以必须判断阶码是否有溢出的情况。


4-1

一、单选题

1.寄存器的值有时是地址,有时是操作数本身,它们在形式没有区别,只有通过( C )才能识别它是数据还是代表地址。

A 寄存器编号   B 判断程序   C 指令操作码或寻址方式位   D 时序信号

指令在执行时,CPU会根据指令操作码字段和寻址方式字段对寄存器中的内容进行解释。若为基址寻址方式,则寄存器中的内容是基地址;若为直接寻址方式,则寄存器中的内容是操作数。所以,通过指令操作码或寻址方式位的解释,可以判断寄存器的内容的种类。

2. 某计算机的单字长指令16位。采用扩展操作码方式,每个地址码4位,三地址指令15条,二地址指令8条,一地址指令127条,零地址指令( A )条

A 16   B15   C 31  D32

对于三地址指令,地址码有12位,操作码有16-12=4位,因此操作码最多有16种。因为三地址指令有15条,所以还剩16-15=1种未用。

对于二地址指令,地址码有8位,操作码有16-8=8位,由于高位操作码一定为1111,所以中间操作码有8-4=4位,因此操作码最多有16种。因为二地址指令有8条,所以还剩16-8=8种未用。

对于一地址指令,地址码有4位,操作码有16-4=12位,由于高位操作码一定为11111,所以中间操作码有12-5=7位,因此操作码最多有128种。因为一地址指令有127条,所以还剩128-127=1种未用。

对于零地址指令,操作码有16位,由于高位操作码一定为111111111111,所以中间操作码有16-12=4位,因此操作码最多有16种。

3 在计算机系统中,描述系统运行状态的是( D

A 程序计数器  B 通用寄存器   C 堆栈指针   D 状态标志寄存器

状态标志寄存器又称为程序状态字,其用来保存程序执行过程中的特征或系统的运行状态,是条件转移指令执行时的依据。

二、分析题


1. 教材(袁),第2版p139 第3题

设相对偏移量为X。因为采用相对寻址方式,且指令共占2个字节,所以可以得到方程:X + 200 + 2 = 100

解得:X = -102

-102的原码为1100110,反码为1011001,补码为1011010。因此该转移指令第二字节的内容应该是-128的补码:1011010。


2. 教材(袁),第2版p139 第4题

  1. 变址寻址方式的有效地址,是变址寄存器的内容与形式地址的加和。
    因此EA = 12 + 1200 H = 000C H + 1200 H = 120C H
  2. 间接寻址地址码是操作数所在存储单元地址所在的存储单元地址。
    因此EA = 1200 H
  3. 寄存器间接寻址地址码是操作数所在的存储单元的地址所存放的寄存器的编号。
    因为指令中给出的寄存器编号为8号,且8号寄存器的内容为1200H。
    因此EA = 1200 H

4-2

本次作业的目的:希望同学们利用校内教学资源和网络资源,通过讨论小组讨论和学习,初步了解MIPS汇编语言和相关调试环境,进一步培养再学习能力。

资料和教学视频在第4章的课程资源中。

1 编程题目

完成MIPS汇编程序设计,从int pof2[6] ={ 1,2,8,4,16,10 } 中找到最大值,调用syscall 显示找到的最大值,syscall可以参考Mars的帮助。

请在Mars 中完成调试运行,记录数组元素所在在内存地址;程序在内存映像,分析转移地址的特点;运行后的寄存器变化。

作业提交:

(1)汇编源程序(**.asm文件)

.data #数字段标注
	array:	.word	1, 2, 8, 4, 16, 10    #类型为.word(int)
	num:	.word	6     #数组的容量
	max:	.space	4     #初始大小空间为4 bytes
.text #代码段开始
main:
	lw	$s1, num      #加载数据:从内存中复制num的内容到寄存器$s1中
	la	$s2, array    #直接寻址:将array中的内存地址存入寄存器$s2中
	la	$s6, max      #直接寻址:将max中的内存地址存入寄存器$s6中
	
	move	$s0, $zero    #将寄存器$zero中的数据存入寄存器$s0中,即$s0=$zero
	move	$t0, $zero    #将寄存器$zero中的数据存入寄存器$t0中,即$t0=$zero
	move	$t7, $zero    #将寄存器$zero中的数据存入寄存器$t7中,即$t7=$zero
	lw	$s5, 0($s2)   #加载数据:使得寄存器 $s2的内容为array
loop:
	sltu    $t1, $s0, $s1	#设置无符号小于运算:含义为if($s0<$s1)   $t1=1 else $t1=0
	beq	$t1, $zero, exit  #设置循环结束条件:若$t1=$zero,则跳转到程序结束段exit
	sll	$t7, $s0, 2		#设置逻辑左移运算: 将寄存器$s0中的内容左移2位存入寄存器$t7中
	add	$t7, $s2, $t7   #加法运算:将寄存器$s2中的内容与寄存器$t7中的内容相加存入寄存器$t7中
	add	$s0, $s0, 1	 # 加法运算,由于$s0 = i,即将寄存器$s0中的内容加一,实现循环指示变量i的自增
	lw	$t3, 0($t7)	 #加载数据:从内存中复制寄存器$t7所存的内容到寄存器$t3中
	slt	$t2, $s5, $t3  #设置小于运算:含义为if($s5<$t3) $t2=1 else $t2=0
	beq	$t2, $zero, loop #设置继续循环条件:若$t2=$zero,则继续loop循环
maxFunction:                     #求两数中较大者的函数
	move	$s5, $t3  #将寄存器$t3中的数据存入寄存器$s5中,即$s5=$t3
	j	loop    #跳转到loop循环当中
exit:
	sw	$s5, 0($s6)   #将寄存器$s5中的数据存入寄存器$s6所存的地址中
	li	$v0, 1  #将需要打印的整型数据赋值到寄存器$v0中
	move	$a0, $s5  #将寄存器$s5中的数据存入寄存器$a0中,即$a0=$s5
	syscall
	li	$v0, 10   #退出
	syscall

(2)记录的调试信息


调试运行及最终输出结果:

记录数组元素所在在内存地址;程序在内存映像,分析转移地址的特点;运行后的寄存器变化;

装载到内存中的程序代码区域称为程序的内存映像,其按存放的内容可以分为3个区。(1)程序区:存放程序指令的区域。(2)静态存储区:存放永久数据区域。(3)动态存储区:存放临时数据的区域。

转移地址的特点是它可以将程序的执行流程转移到指定的内存地址,使程序执行到不同的代码段中。这种特点可以用于实现函数调用、跳转语句等程序控制流转移的功能。

ADD指令会将两个寄存器中的值相加后把结果存放到另一个寄存器中。

MOVE指令会将一个寄存器中的值存入另一个寄存器中。

LW/LA指令会将值或地址存入一个寄存器中。

老师提供的参考代码逐句解读:

代码

解释

.data

数据域开始

array: .word 1,2,8,4,16,10

定义数组array

num:   .word  6

定义数组长度num

max:   .space 4

定义起始空间space

.text

代码段开始

main:

主函数部分

lw $s1,num     # $s1=6

令$s1存放num

la $s2,array   # address of  array

令$s2存放array地址

la $s6,max     # $6=max

令$s6存放max地址

move   $s0, $zero           # i=0

令$s0为0,为for循环的计数变量

move   $t0, $zero           # t0=0

令$t0为0

move   $t7, $zero           # t7=0

令$t7为0

lw  $s5,0($s2)              # load array

加载array,读取地址为$s2加0的数据并存储到$s5寄存器中

此时应该是array[0]

for_loop:  sltu   $t1, $s0, $s1       # if i<num, $t1=1; if i>=num $t1=0

For循环部分

比较$s0和$s1(即i和num)

如果i<num,则$t1=1

否则$t1=0

           beq    $t1, $zero, exit    # if $t1=0, jump to exit

判断$t1是否与0相等

如果相等,则退出循环

否则继续循环

           sll    $t7, $s0, 2         # i×4

设置逻辑左移

将$s0的内容左移2位存入$t7

$s0为i

           add    $t7, $s2, $t7       # $t7:address of array[i]  

将$s2的内容与$t7的内容相加

结果存入$t7

此时$t7为array[i]的地址

           add    $s0,$s0,1

将$s0自增1

即i++

           lw     $t3,0($t7)

加载,读取地址为$s7加0的数据并存储到$t3寄存器中

即$t3=array[i]

           slt    $t2,$s5,$t3   #comapre $5 $t3

小于运算,如果$s5<$s3,则$t2=1

否则,$t2=0

           beq    $t2, $zero,loop                 

判断相等,如果$t2=0,则继续循环

           max2: move $s5,$t3

Max函数

令$s5为$t3

即把$s5更新为当前的max number

loop:     j      for_loop

循环使用for_loop

exit:    sw $s5,0($s6)

写入,将$s5中的数据写入$s6+0的存储单元

         li $v0,1 # syscall  service number in register $v0

将1加载到$v0

         move $a0,$s5  # $a0 = integer to print

将$s5的值移到$a0

$a0可以进行int类输出

         syscall

请求执行

         li $v0 10

将10加载到$v0

         syscall

请求执行

2 分析题

从“在线教育综合平台”下载ch4_mpis2.asm文件(书中P135-138 例4.10),在MIPS汇编程序模拟环境Mars 中打开(Mars的资料也在平台),采用单步运行方式,参照P131-138页的内容,完成以下问题:

ch4_mpis2.asm

1, 哪些寄存器一般用于存放非浮点入口参数?本程序中用到哪几个寄存器来存放入口参数?

2, 返回参数一般放在哪个寄存器?

3, 记录过程中堆栈增长的方向?

4, 哪条指令是用于过程调用的?返回地址是自动保存的吗?

5, 返回指令采用哪条指令?

6, set_array 、compare、sub哪个过程是叶过程?

7, 过程帧(帧)与栈的关系?记录一次调用过程中,set_array, compare 过程 $fp以及$fp的变化。

8, 记录set_array 过程第2次调用 compare、sub 过程后,$s1、$s7 的内容?

9, 记录set_array 过程第4次调用 compare、sub 过程后,局部数组array中各元素的值。

(1)一般用于存放非浮点入口参数的寄存器为$a0—$a3。本程序中用到$a0存放num。

(2)返回参数一般放在寄存器$v0。

(3)堆(heap)的增长方向是向上增长,即低地址向高地址增长。栈(stack)的增长方向是向下增长,即高地址向低地址增长。

(4)【jal set-array】【jal compare】、【jal sub】指令是用于过程调用的。返回地址是自动保存的,且保存在$ra中。

(5)返回指令采用【jr $ra】。

(6)sub过程是叶过程,因为其不再调用其他过程的过程。Compare过程调用sub过程,set-array过程继续调用后续过程,因此二者均不是叶过程。

(7)过程帧是指在函数调用过程中为存储函数局部变量、参数和返回地址等信息而开辟的存储空间,是实现函数调用和返回的关键。而栈则是实现过程帧的一种数据结构。每当函数被调用时,都会在栈上开辟一个新的过程帧,并将所需信息存储在其中。函数返回时,栈顶的过程帧被弹出,控制权返回给上一层函数。其中,$fp(frame pointer)指向当前帧的底部,$sp(stack pointer)指向当前帧的顶部。

在记录调用过程中,set_array 函数的调用会导致 $fp 的值被更改为新的栈帧的地址。而 compare 函数的调用则会在当前栈帧中进行,不会更改 $fp 的值。在函数调用结束后,$fp 的值会被恢复为上一个栈帧的地址。

一次调用过程中,set_array, compare 过程 $fp以及$fp的变化如下:

  • 调用set-array前,$fp和$sp值相同,指向栈顶。
  • 执行jal set-array后,系统把$ra、$fp、$s1寄存器的值存入堆栈,$fp指向当前帧的底部,$sp向下移动并给过程调用分配空间。
  • 在set-array过程中,$sp指向当前过程栈顶位置,$fp指向当前过程的底部。
  • 调用compare时,系统将$ra、$fp、$s7寄存器的值存入堆栈,$fp指向当前帧的底部,$sp向下移动并给过程调用分配空间。
  • 执行compare后,返回set-array,系统从堆栈中回复$ra、$fp、$s7的值,$fp和$sp值回到set-array前的状态。

(8)set_array 过程第2次调用compare、sub过程后,$s1、$s7的内容分别为:array首地址,arrayc首地址。

(9)set_array 过程第4次调用compare、sub过程后,局部数组array中各元素的值为:[5,4,3,2]


5-1

1.袁春风《计算机组成与系统结构》第2版p190第1题:指令周期,数据通路,操作元件,状态元件

指令周期:CPU取出并执行一条指令所需的时间,包括取指、译码、执行、访问存储器和写回等多个阶段。

数据通路:指令执行过程中数据所经过的路径,包括路径上的部件。数据通路就是由操作元件和存储元件通过总线或分散方式连接而成的进行数据存储、处理和传送的路径。

操作元件:输出只取决于当前的输入。组合电路的定时不受时钟信号的控制,所有输入信号到达后,经过一定的逻辑门延迟,输出端的值被改变,并一直保持其值不变,直到输入信号改变。常见的操作元件为多路选择器MUX、加法器Adder、算术逻辑部件ALU、译码器Decoder。

状态元件:具有存储功能,输入状态在时钟控制下被写到电路中,并保持电路的输出值不变,直到下一个时钟到达。输入端状态由时钟决定何时被写入,输出端状态随时可以读出。

2.袁春风《计算机组成与系统结构》第2版p190第2题(1)(2)(3)

(1)CPU的基本组成和基本功能各是什么?

CPU主要由数据通路和控制单元组成。数据通路中包含组合逻辑单元和存储信息的状态单元。控制单元对取出的指令进行译码,并与指令执行得到的条件码等组合,生成对数据通路进行控制的控制信号。

CPU的基本功能是执行指令,包括指令的获取、解码、执行和结果返回等,以实现计算机的各种功能。

(2)取指令部件的功能是什么?

取指令部件可以实现从程序寄存器指出的内存单元取出指令,并将指令送到指令寄存器中,同时计算下一条指令的地址并将其送到程序寄存器中。

(3)控制器的功能是什么?

控制整个计算机的运行,包括指令的获取、解码、执行以及数据的传输等,即对指令进行译码,将译码的结果和状态/标志信号和时序信号等进行组合,产生各种操作控制信号。这些控制信号被送到CPU内部、主存或I/O模块中。控制器是整个CPU的指挥控制中心,通过规定各个部件的操作行为来控制数据的流动,从而完成指令的执行。

3.下图为双总线结构某模型机器的数据通路:

IR为指令寄存器

PC为程序计数器(具有自增功能)

AR为主存地址寄存器

DR为数据寄存器

ALU由+、-控制信号决定完成何种操作,控制信号G控制一个门电路;

M为主存(受R/W信号控制)。另外,线上标注有控制信号,例如Yi表示Y寄存器的输入控制信号,R1o为寄存器R1的输出控制信号,未标字符的线为直通线,不受控制。

问题:“SUB R3,R0”指令完成(R3)-(R0)→R3的功能操作,试画出其指令周期流程图(假设该指令的地址已放入PC中),并列出相应的微操作控制信号序列。

 流程图:

微操作控制信号序列:

PCo, G, ARi

R/W=R

DRo, G, IRi

R3o, G, X

R0o, G, Y

-, G, R3i


6-1

 

1.袁春风,《计算机组成与系统结构》(第2版),p288, 2(1)-(3)

(1)每种单独的存储器都无法同时保证速度快、容量大、价格便宜,所以需要构建层次化存储体系结构。层次化的存储器体系结构由Cache、主存、辅助存储器三级体系构成。

(2)SRAM芯片的记忆单元采用6管静态MOS管存储电路,其具有功耗大、集成度低、速度快、无须再生和刷新等特点,适合用于构成如cache等的高速小容量存储器。DRAM芯片的记忆单元采用单管动态MOS管存储电路,其具有功耗低、集成度高、速度慢、需要定时刷新等特点,适合用于构成如主存等的慢速大容量存储器。

(3)CPU和主存之间有同步定时和异步定时两种通信定时方式,SDRAM芯片采用同步定时方式与CPU交换信息。


2袁春风,《计算机组成与系统结构》(第2版),p288, 3

(1)DRAM芯片个数 = 4GB/512MB = 8个。

(2)构建2GB的主存时需要4个内存条。

(3)按字节编址,即主存地址有16位。A15~A0中,A9-A0为DRAM内地址,A9-A5为片内的行地址,A4-A0为片内的列地址,A15-A10用于选择芯片。


6-2

根据直接映射的cache工作原理,针对一个8行的cache工作过程进行仿真,每行(块)为一个字,1字4字节,需要读取的内存地址在trace.txt文件中列出。请编写程序,实现8行的cache工作过程进行仿真,可显示每个内存地址、是否命中、命中率。

一、程序代码

#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

struct address {
	int flag[29];  //记录标志位 
	bool data;  //判断块中是否有数据
}; 

int main(){
	char buffer[11];
	int buff[8],binbuff[32],a[4]={8,4,2,1};
	int i,j,temp=0,count=0,n=0,data=1;
	struct address Cache[8];
	//读取路径文件
	ifstream in("C:/Users/86158/Desktop/trace.txt");
	//打开文件失败,退出
	if(!in.is_open()){
		cout<<"打开文件失败";
		exit(1);
	}
	while(!in.eof()){
		in.getline(buffer,11);
		n++;
		temp=0;
		data=1;
		cout<<"16进制地址:"<<buffer<<endl;  //读地址
		//将16进制转化2进制
		for(i=0;i<8;i++){
			switch (buffer[i+2]) {
			    case 'A':
				    buff[i] = 10;
				    break;
			    case 'B':
				    buff[i] = 11;
				    break;
			    case 'C':
				    buff[i] = 12;
				    break;
			    case 'D':
				    buff[i] = 13;
				    break;
			    case 'E':
				    buff[i] = 14;
				    break;
			    case 'F':
				    buff[i] = 15;
				    break;
			    default:
				    buff[i] = buffer[i+2]-'0';
				    break;
			}
			for(j=0+i*4;j<4+i*4;j++){
				binbuff[j] = buff[i]/a[j-i*4];
				buff[i] %= a[j-i*4];
			}
		}
		cout<<"二进制地址:";
		for(i=0;i<32;i++){ 
			cout<<binbuff[i];
		} 
		cout<<endl;
		for(i=27;i<30;i++){ 
			temp += pow(2,29-i)*binbuff[i];
		}
		//cache中没有信息
		if(Cache[temp].data==0){
			cout<<"结果:未命中"<<endl;
			//改变cache状态
			Cache[temp].data=1;  
			for(i=0;i<27;i++){
				//将数据拷入cache中 
				Cache[temp].flag[i] = binbuff[i];  
			} 
		}
		else{
			for(i=0;i<27;i++){
				if(Cache[temp].flag[i]!=binbuff[i]){
				    //标志位与cache中不符则Miss 
					cout<<"结果:未命中"<<endl;  
					data=0;
					break;
				}
			}
			if(data!=1){
				for(i=0;i<27;i++){
					Cache[temp].flag[i]=binbuff[i];
				}		
		    }
			else{
				count++;
				cout<<"结果:命中"<<endl;
			}
		}
		cout<<endl;
	}
	cout<<endl<<"命中数: "<<count<<endl;
	cout<<"总数: "<<n<<endl;
	double rate=double(count)/n*100; 
	printf("命中率: %.2lf%%",rate);
	return 0;
}

二、实验结果截图(命中率)

运行结果示例截图:

命中率的最终截图:

 

运行结果文字汇总:

16进制地址:0x80000000

二进制地址:10000000000000000000000000000000

结果:未命中

16进制地址:0x80000004

二进制地址:10000000000000000000000000000100

结果:未命中

16进制地址:0x80000008

二进制地址:10000000000000000000000000001000

结果:未命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:未命中

16进制地址:0x00000020

二进制地址:00000000000000000000000000100000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:未命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:未命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:未命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000024

二进制地址:00000000000000000000000000100100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000028

二进制地址:00000000000000000000000000101000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x0000002C

二进制地址:00000000000000000000000000101100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:未命中

16进制地址:0x00000030

二进制地址:00000000000000000000000000110000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:未命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000034

二进制地址:00000000000000000000000000110100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:未命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000038

二进制地址:00000000000000000000000000111000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:未命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x0000003C

二进制地址:00000000000000000000000000111100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000040

二进制地址:00000000000000000000000001000000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000044

二进制地址:00000000000000000000000001000100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000048

二进制地址:00000000000000000000000001001000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x0000004C

二进制地址:00000000000000000000000001001100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:未命中

16进制地址:0x00000050

二进制地址:00000000000000000000000001010000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:未命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000054

二进制地址:00000000000000000000000001010100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:未命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000058

二进制地址:00000000000000000000000001011000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:未命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x0000005C

二进制地址:00000000000000000000000001011100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000060

二进制地址:00000000000000000000000001100000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000064

二进制地址:00000000000000000000000001100100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x00000068

二进制地址:00000000000000000000000001101000

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

16进制地址:0x8000000C

二进制地址:10000000000000000000000000001100

结果:命中

16进制地址:0x0000006C

二进制地址:00000000000000000000000001101100

结果:未命中

16进制地址:0x80000010

二进制地址:10000000000000000000000000010000

结果:命中

16进制地址:0x80000014

二进制地址:10000000000000000000000000010100

结果:命中

16进制地址:0x80000018

二进制地址:10000000000000000000000000011000

结果:命中

命中数: 68

总数: 103

命中率: 66.02%


7-1

1:第2版 p 345 第1题 给出以下概念的解释(前8行)

第一行:

I/O带宽:单位时间内系统输入/输出的数据量或所完成的I/O操作次数。即指在一定时间内所完成的工作量,也称为吞吐率。

响应时间:是指从作业提交开始道作业完成所用的时间,也称为等待时间。

编码键盘:也称数字键盘或小键盘,通常位于键盘的右侧,包含数字键、运算符、小数点和回车键等。它们通常用于数值输入和计算,比如在电子表格中输入数据或进行财务会计工作。

非编码键盘:是指标准的 QWERTY 键盘布局,包含字母键、符号键和功能键等。它们通常用于文字输入、网页浏览、游戏操作等。

第二行:

键盘扫描码:是指计算机在接收到键盘输入时,将键盘按键转换为数字代码的过程中所使用的码。每个按键都有一个特定的扫描码,这些码可以通过键盘控制器读取。通常情况下,键盘扫描码是由硬件生成,并且不依赖于操作系统或软件程序。在现代计算机中,常见的键盘扫描码包括 ASCII 码、Extended ASCII 码、Unicode 码等。

终端:是指一种由CRT显示器、控制器及键盘合为一体的设备,它与微型计算机的根本区别是没有自己的中央处理单元CPU,同时没有内存。主要功能是将键盘输入的请求数据发往主机并将主机运算的结果显示出来。

磁道:磁盘在高速旋转时,磁头相当于磁盘表面做相对运动。相对运动时磁头在盘面所经过的路径构成一个磁道。磁头在不同的位置,磁盘表面就形成不同半径的同心圆,因此每个同心圆为一个磁道。每个磁道都有一个编号,最外面的是0磁道。

柱面:在一个磁盘驱动器中的若干个盘片都连到同一个中心轴上,每个可读写的盘面上都有一个磁头,这些不同盘面上的磁头被连在一起且同时按相同的轨迹移动。因此,在不同盘面上的磁头总是处在相同半径的磁道上,所有盘面上的这些磁道构成一个柱面。因此,柱面号和磁道号是一样的。磁头号和盘面号是一样的。

第三行:

扇区:每个磁道被划分为若干扇区,每个扇区的存储容量为512B或4096B。每个扇区都有一个编号。扇区是磁盘的最小编址单位,因此到磁盘上寻找数据时,只需定位到相应的扇区。读写数据时可能会以多个扇区为单位进行传输。

道密度:沿磁盘半径方向单位长度上的磁道数称为道密度。道密度的单位是道/英寸或道/毫米。道密度是相邻磁道间距的倒数。

位密度:沿磁道方向上单位长度所记录的二进制信息位叫位密度。

平均存取时间:寻道和旋转操作时间的平均值之和,即平均寻道时间加平均旋转时间。

第四行:

寻道时间:移动磁头使磁头定位到要读写的磁道上的操作称为寻道,在该操作上使用的时间称为寻道时间。

旋转等待(查找)时间:旋转等待时间指的是在磁盘寻道时,磁头需要移动到所需数据所在的磁道上并等待该磁道旋转到磁头所在位置的时间。

传输时间:当磁头正好落在要读写数据的起点后,就开始读/写数据,磁盘读/写一块数据(即一个扇区)的时间为传输时间。

数据传输率:分为外部数据传输率和内部数据传输率两种。外部数据传输率指主机接口从/向硬盘缓存读出/写入数据的速度;内部数据传输率指磁头定位在要读写的数据块的始端后,单位时间内连续从磁道中读出或写入的二进制数据的位数。

第五行:

磁盘控制器:指用来控制磁盘进行数据读写,并控制数据在磁盘和主存间进行传输的部件。

冗余磁盘阵列(RAID):是一种数据存储技术,通过将多个独立的硬盘驱动器组合在一起,以提高数据容错性和性能。RAID通过在多个硬盘驱动器之间分配数据和奇偶校验码来实现数据冗余和容错。当其中一个硬盘驱动器出现故障时,RAID可以自动恢复数据并且不会影响系统的正常运行。

I/O接口:是指计算机与外部设备进行数据交换的接口。它是计算机与外界交互的重要途径。

I/O控制器:I/O接口中的控制电路,不包含I/O接口中的连接器插座。

第六行:

I/O端口:I/O接口中一些可被程序访问的寄存器,用来存放控制、数据和状态等信息。

命令(控制)端口:在I/O接口中,用来存放CPU送来的控制信息的寄存器,只可对其进行写操作。

数据端口:在I/O接口中,用于存放接收和发送数据的寄存器,可以对其进行读或写操作。

状态端口:在I/O接口中用来记录外部设备或I/O接口的状态的寄存器,通常只可以对其进行读操作。

第七行:

I/O空间:所有I/O端口号组成的地址空间。

独立编址:将I/0端口和主存单元分别编号,不占用主存单元的地址空间,因而主存单元和I/0端口可能会有相同的编号,但地址位数大多不同,主存单元多,地址空间大,因而地址位数多;I/0端口少,地址空间小,因而地址位数少。因为可能有相同的编号,指令中无法靠地址来区分要访问的是主存单元还是 I/O 端口,所以需要有和访存指令不同的操作码,因此需要设计专门的I/O 指令。

统一编址:I/O端口和主存单元统一编址,所以也称为储器映射I/O方式,一个地址空间分成了两部分,各在不同的地址段中,但地址的位数是相同的,可根据地甚范围的不同来区分访问的是主存单元还是 I/O 端口,所以无需专门的输入输出指令。

存储器映射I/O口:是一种将I/O设备的寄存器映射到处理器的内存地址空间中的技术。实现原理是:将I/O设备的寄存器地址与处理器的内存地址进行映射,使得处理器可以通过访问内存地址的方式来访问I/O设备的寄存器。这样,处理器读写内存地址时,实际上就是对I/O设备的寄存器进行读写操作,从而完成对I/O设备的控制和数据传输。

第八行:

I/O指令:用来访问I/O端口的指令。

程序查询I/O:CPU通过执行查询程序来完成对外设的控制,实现和外设的数据传送。在查询程序中,CPU首先通过读取状态端口中的状态信息,了解接口是否已“就绪”(或“完成”),若是,就通过数据端口进行新的数据传送,并查询外设是否空闲,在外设空闲的情况下,通过发送控制信息到命令端口,然后由接口发“启动”命令送外设;如果接口没有就绪,或外设不空闲,则CPU继续查询,以等待接口就绪或外设空闲。所有信息(包括控制、数据、状态)的交换由查询程序中的I/O指令完成。

就绪状态:对于输人设备而言,就绪状态意味着I/0接口中的数据缓冲器已准备好,CPU可以从I/0接口取数据;对于输出设备而言,则说明I/0接口中的数据缓冲器已空,CPU可以将数据送到I/0接口中。

程序中断I/O:程序中断 I/0方式下,CPU启动外设后,就转到另外一个程序执行,此时,外设和 CPU并行工作。一旦外设完成任务,便发中断请求给 CPU,告知 CPU 上次任务已经完成。此时,CPU暂停正在执行的程序,转到一个中断服务程序进行中断处理,在中断处理过程中,进行外设下一步的准备工作(例如,传送下一个要打印的数据,或者取走键盘数据或采样数据,为下次输入腾空数据缓冲寄存器,等等),最后启动外设,并回到原程序继续执行。此时CPU和外设又能并行工作。

2第2版 p 345 第2题 (1)-(4)

(1)什么是I/O接口?I/O的基本功能有哪些?按数据传送方式分有哪两种接口类型?

I/O接口是指计算机系统中,负责主机和外部设备之间数据传输的一种硬件电路。

I/O的基本功能包括输入、输出和中断处理。

按数据传送方式分,I/O接口有串行接口和并行接口两种类型。

(2)串行接口和并行接口的特点各是什么?

  1. 串行接口:数据是通过一根线按位依次传输的,传输速率相对较慢,但可以使用较长的传输线路。典型的串行接口包括串口和USB接口。

  1. 并行接口:数据是通过多根线同时传输的,传输速率相对较快,但受限于传输距离和线路数量。典型的并行接口包括并口和PCI总线。

(3)CPU如何进行设备的寻址?I/O端口的编址方式有哪两种?各有何特点?

CPU通过地址总线向系统总线发送地址信号,让系统总线连接的设备进行响应。设备通过地址识别电路判断是否是自己需要响应的地址,如果是,则进行数据传输;如果不是,则不做响应。CPU根据总线协议规定的访问方式,向设备发送读写命令和数据,设备根据命令进行相应的操作。

I/O端口的编址方式主要有两种:基于端口号编址和基于内存映射编址。

  1. 基于端口号编址:这种方式下,每个I/O设备都被赋予了一个唯一的端口号。程序每次需要与设备进行通信时,都需要指定设备的端口号。
  2. 基于内存映射编址:这种方式下,I/O设备被映射到计算机的内存地址空间中,程序通过读写内存地址的方式与设备进行通信,同时可以像访问内存中的数据一样访问I/O设备。

(4)什么是程序查询I/O方式?说明其工作原理。

CPU通过执行查询程序来完成对外设的控制,实现和外设的数据传送。

在查询程序中,CPU首先通过读取状态端口中的状态信息,了解接口是否已“就绪”(或“完成”),若是,就通过数据端口进行新的数据传送,并查询外设是否空闲,在外设空闲的情况下,通过发送控制信息到命令端口,,然后由接口发“启动”命令送外设;如果接口没有就绪,或外设不空闲,则CPU继续查询,以等待接口就绪或外设空闲。所有信息(包括控制、数据、状态)的交换由查询程序中的I/O指令完成。

3  选择题

①  在独立编址方式下,存储单元和I/O设备是靠______来区分的。

A.不同的地址和指令代码

B.不同的数据和指令代码

C.不同的数据和地址

D.不同的地址

②下列关于磁盘存储器的叙述中,错误的是

A.磁盘的格式化容量比非格式化容量小

B.扇区中包含数据、地址和校验等信息

C.磁盘存储器的最小读写单位为一个字节

D.磁盘存储器由磁盘控制器、磁盘驱动器和盘片组成

4 某计算机系统中的磁盘有300个柱面,每个柱面有10个磁道,每个磁道有200个扇区,扇区大小为512 B。文件系统的每个簇包含2个扇区。清回答下列问题:

(1)磁盘的容量是多少?

(2)第100 530簇(簇号)在磁盘上的物理地址是什么?

磁盘容量 = (300*10*200*512/1024) KB = 3*10^5 KB

每个柱面有10*200 = 2000个扇区,每个簇含有2个扇区,因此每个柱面有2000/2 = 1000个簇。

簇号100 530的柱面号为 [100530 / 1000] = 100(取整后的结果)

100530 % 1000 = 530(取余后的结果)

磁头号为 [530 / (200/2)] = 5

扇区号为 (530*2) % 200 = 60


 7-2

1:假定计算机的主频为500MHz,CPI为4。现有设备A和B,其数据传输率分别为2 MB/s和40 MB/s,对应I/O接口中各有一个32位数据缓冲寄存器,请回答以下问题:

(1)若设备A采用定时查 I/0方式,每次输入/输出都至少执行10条指令。设备A最多间隔多长时间查询一次才能不丢失数数据?CPU用于设备A输人/输出的时间占CPU总时间的百分比?

程序定时向缓存端口查询数据,必须在传输完端口大小的数据时访问端口,以防止部分数据未被及时读取而丢失。

设备A准备32位数据用时4B/2MB=2us,因此最长间隔时间为2us。

每秒查询次数至少是1s/2us=5*10^5次,每秒CPU用于设备A的输入输出时间至少为5*10^5*10*4=2*10^7个时钟周期,占CPU总时间为2*10^7/500M=4%。

(2)在中断I/0方式下,若每次中断响应和中断处理的总时钟周期数至少为400,则设备B能否采用中断I/0方式?为什么?

不能。

中断响应和中断处理的时间为400*(1/500M)=0.8us,准备32位数据用时4B/40MB=0.1us。

因此,准备数据的时间小于中断响应和中断处理的时间,数据会被刷新,造成丢失。

(3)若设备B采用DMA方式,每次DMA传送的数据块大小为1000 B ,CPU用于DMA预处理和后处理的总时钟周期数为500,则CPU用于设备B 输人/输出的时间占CPU总时间的百分比最多是多少?

DMA只有预处理和后处理需要CPU处理,数据的传送过程是由DMA控制。

设备B每秒DMA次数最多为40MB/1000B=40000,CPU用于设备B输入输出的时间最多为40000*500=2*10^7个时钟周期,占CPU总时间最多为2*10^7/500M=4%。


 

2:教材 第2版 p347 13(1)

1级中断的处理优先级最高,说明1级中断对其他所有中断都屏蔽,其屏蔽字段全为1。3级中断的处理优先级最低,说明其除了本身对其他中断都开放。最终的中断屏蔽位如下表所示:

中断处理程序级别

1

2

3

4

5

1

1

1

1

1

1

2

0

1

1

0

0

3

0

0

1

0

0

4

0

1

1

1

1

5

0

1

1

0

1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/736622.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java.sql.SQLException: connection holder is null

一、工作中遇到的问题汇总 1、java.sql.SQLException: connection holder is null&#xff1b; 问题描述&#xff1a;对于大表进行查询、修改操作时&#xff0c;有时sql需要执行很长时间&#xff0c;这时就可能在执行到半路时、报错SQLException: connection holder is null。…

时间序列分析波动性预测GARCH模型

GARCH&#xff08;Generalized Autoregressive Conditional Heteroskedasticity&#xff09;模型是一种常用于预测金融时间序列波动性的统计模型。它是ARCH&#xff08;Autoregressive Conditional Heteroskedasticity&#xff09;模型的扩展&#xff0c;通过引入对过去波动性的…

python怎么获取免费代理IP

什么是免费代理IP 免费代理IP是指可以免费使用的代理服务器的IP地址。代理服务器充当客户端和目标服务器之间的中间人&#xff0c;通过转发请求和响应来实现网络数据的传输。使用代理IP可以隐藏真实的客户端IP地址&#xff0c;实现匿名访问网络资源。 免费代理IP通常由个人或组…

【Java】自定义对象作为HashMap的键,同时重写hashCode和equals方法

如果要将自定义类的实例 作为HashMap的 键&#xff0c;必须重写hashCode和equals方法 简单版本&#xff0c;看不懂看后面复杂版本解释 复杂版本解释 当我们用 HashMap存入自定义的类时&#xff0c;如果不重写这个自定义类的equals和hashCode方法&#xff0c;得到的结果会和我们…

3.精通RabbitMQ—基础 RabbitMQ知识、进阶 RabbitMQ知识

本文目录如下&#xff1a; 什么是 RabbitMQ?什么是 消息中间件?RabbitMQ 的应用场景&#xff1f;RabbitMQ 中主要包含哪几个部分&#xff1f; 精通 RabbitMQ&#xff0c;从认识开始 什么是 RabbitMQ? RabbitMQ 整体上是一个 生产者与消费者模型&#xff0c;主要负责 接收、…

Redis的一个大Key

什么是 redis 的大 key? redis 的大 key 不是指存储在 redis 中的某个 key 的大小超过一定的阈值&#xff0c;而是该 key 所对应的 value 过大对于 string 类型来说&#xff0c;一般情况下超过 10KB 则认为是大 key&#xff1b;对于set、zset、hash 等类型来说&#xff0c;一…

无线通信模块接口类型_USB/SDIO/UART接口wifi模块特性

无线通信模块接口,简单来说设备需要与外部设备交换数据的通讯接口,如工程师常提到的USB接口,UART接口,SDIO接口,I2S接口,I2C接口,WAN口,LAN口,SPI接口,以太网接口(RJ-45接口)等。 原文链接:http://www.skylab.com.cn/newsview-2768.html 1、USB接口 USB接口是平…

Git gui教程---第六篇 Git gui的使用 变动,提交

变动&#xff0c;提交 修改TEST.txt的内容&#xff0c;并且点击重新扫描&#xff0c;则TEST文件会出现在未缓存的窗口中 像前面教的一样&#xff0c;缓存后&#xff0c;添加描述后提交&#xff0c;并且打开历史记录可以查看到提交的变动。我这里会新增一个文件并且提交多几次&…

N天爆肝数据库——MySQL(2)

本篇文章&#xff0c;主要对DML DQL进行知识总结和学习。 期待和大家一起学习进步。DML-介绍 DML(数据库操作语言)&#xff0c;用来对数据库中表的数据 记录进行增删改操作。 添加数据&#xff08;INSERT&#xff09; 修改数据&#xff08;UPDATE&#xff09; 删除数据&#…

计算机毕业论文内容参考|基于Java的城乡低保信息管理系统的设计和实现

文章目录 导文摘要:前言:绪论:1课题背景:2国内外现状与趋势:3课题内容:相关技术与方法介绍:系统分析:系统设计:系统实现:系统测试:总结与展望:1本文总结:2后续工作展望:导文 这里是导文计算机毕业论文内容参考|基于Java的城乡低保信息管理系统的设计和实现 摘要:…

C++图形开发(10):移动的方块

文章目录 1.引入2.静止的方块3.移动的方块 1.引入 那么我们今天就来实现一下矩形的移动 注意&#xff1a;本篇文章的内容都是基于此前用空格控制的小球的基础上进行开发的&#xff0c;详见&#xff1a;C图形开发&#xff08;8&#xff09;&#xff1a;空格键控制小球起跳 先来…

PHP实现微信小程序推送消息至公众号

1、申请微信小程序和公众号必须是同一个主体 2、小程序和公众号必须要认证 3、公众号是服务号&#xff0c;接收消息必须关注公众号 4、公众号后台配置 开通模版服务 申请模版&#xff0c;获取模板消息的ID 关联小程序 获取公众号appid 5、小程序后台获取appid&#xff0c;a…

常用异常检测算法总结记录

这篇博文主要是延续前文系列的总结记录&#xff0c;这里主要是总结汇总日常主流的异常检测算法相关知识内容。 &#xff08;1&#xff09;基于统计方法的异常值检测 基于统计方法的异常值检测是一种常用的异常检测算法&#xff0c;它基于样本数据的统计特性来识别与其他样本显…

华为OD机试真题 Java 实现【阿里巴巴找黄金宝箱(I)】【2023 B卷 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 一、题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上&#xff0c;无意中发现了强盗集团的藏宝地&#xff0c;藏宝地有编号从0~N的箱子&#xff0c;每个箱子上面贴有…

如何从一个仪表盘管理多个WordPress网站?

您是否正在寻找一种管理多个WordPress网站的简单方法&#xff1f; 监控多个网站并使其保持更新可能非常耗时。 幸运的是&#xff0c;有几种 WordPress 管理工具可以让您从单个仪表板管理多个 WordPress 网站变得非常容易。这将帮助您节省大量时间&#xff0c;同时使所有 Word…

【Java】堆和优先级队列PriorityQueue

文章目录 一、堆1.1 堆的概念1.2 堆的存储方式1.3 堆的创建1.4 堆的插入与删除1.5 堆的应用场景 二、 优先级队列2.1 什么是优先级队列2.2 堆模拟实现优先级队列 三、Java中的PriorityQueue3.1 PriorityQueue的特性3.2 常用方法 一、堆 1.1 堆的概念 在数据结构中&#xff0c…

Python实现PSO粒子群优化算法优化随机森林回归模型(RandomForestRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 PSO是粒子群优化算法&#xff08;Particle Swarm Optimization&#xff09;的英文缩写&#xff0c;是一…

虚拟机的安装

1.选择自定义安装 然后下一步 2.选择稍后安装操作系统,也可以选择2 直接安装 3. 选择Linux和相关版本 4.命名虚拟机 默认都是C盘,修改一下好点 5.分配处理器 看需要同时开几台虚拟机,同时也看一下自己的CPU,处理器默认选1个就行,内核数量 选择为 逻辑处理器数量/同时开的虚…

easyupload

红框位置是上传后的提示 依次尝试上传&#xff0c;发现php,phtml.php3&#xff0c;php5&#xff0c;双写等都不行 .htaccess文件也不行 尝试.php. 绕过 (windows中会把后缀名最后的空格和. 省略&#xff0c;即上传.php.绕过后会变为.php) 加入图片头的php文件也不行 但是加入文…

Gitlab 新项目搭建

文章目录 Gitlab 新项目搭建新建空白项目初始化本地仓库并提交建立本地仓库和远程仓库关系并推送 Gitlab 新项目搭建 新建空白项目 项目名称与本地新建项目名称相同 初始化本地仓库并提交 进入本地项目根目录下&#xff0c;右击 git bash here打开命令窗口&#xff1b;初始化…