目录
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)
- 冯·诺依曼计算机由哪几部分组成?各部分的功能是什么?采用什么工作方式?
答:
由运算器、控制器、存储器、输入设备、输出设备五大基本部件组成。
各部分在功能上表现为:运算器:用于完成各种算术运算、逻辑运算和数据传送等数据加工处理。控制器:用于控制程序的执行,是计算机的大脑。运算器和控制器组成计算机的中央处理器(CPU)。控制器根据存放在存储器中的指令序列(程序)进行工作,并由一个程序计数器控制指令的执行。控制器具有判断能力,能根据计算结果选择不同的工作流程。存储器:用于记忆程序和数据,例如:内存。程序和数据以二进制代码形式不加区别地存放在存储器中,存放位置由地址确定。输入设备:用于将数据或程序输入到计算机中,如鼠标、键盘等。输出设备:将数据或程序的处理结果展示给用户,如显示器、打印机等。
各部分在工作方式上表现为:不同部件之间通过指令进行控制和数据传递的行为。
- 摩尔定律的主要内容是什么?
答:
摩尔定律是英特尔创始人之一戈登·摩尔的经验之谈,其核心内容为:集成电路上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍。换言之,处理器的性能大约每两年翻一倍,同时价格下降为之前的一半。
- 计算机系统的层次结构如何划分?计算机系统的用户可分为哪几类?每类用户工作在哪个层次?
答:
计算机系统的层次结构可划分为:硬件 + 软件。硬件部分包括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:
- 对于P1,M2快,比M1快1倍。对于P2,M1快,比M2快1倍。
- 对于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倍。 - 执行P1时的平均时钟周期数,M1为10*800M/(200*10^6)=40,M2为5*1.2G/(150*10^6)=40。
- 对于P1主要关心响应时间,即执行时间越短且价格越低,性价比越好。对于M1,10*5000=50000,对于M2,5*8000=40000。
因此应该选择M2,因为M2的执行时间*价格更小,性价比更高。 - 采用算数平均方式计算时,对于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:
- MIPS=f/(CPI*10^6),峰值MIP要求CPI为最小值。
所以M1的峰值MIPS为1000/1=1000MIPS,M2的峰值MIPS为1500/2=750MIPS。 - 五类指令占比均为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结构,完成以下内容:
每一步迭代过程:
- 取乘数的最低位Yn-i判断。
- 若Yn-i的值为1,则将上一步迭代部分积Pi与X相加;若Yn-i的值为0,则什么也不做。
- 右移一位,产生本次部分积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题
- 变址寻址方式的有效地址,是变址寄存器的内容与形式地址的加和。
因此EA = 12 + 1200 H = 000C H + 1200 H = 120C H - 间接寻址地址码是操作数所在存储单元地址所在的存储单元地址。
因此EA = 1200 H - 寄存器间接寻址地址码是操作数所在的存储单元的地址所存放的寄存器的编号。
因为指令中给出的寄存器编号为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)串行接口和并行接口的特点各是什么?
- 串行接口:数据是通过一根线按位依次传输的,传输速率相对较慢,但可以使用较长的传输线路。典型的串行接口包括串口和USB接口。
- 并行接口:数据是通过多根线同时传输的,传输速率相对较快,但受限于传输距离和线路数量。典型的并行接口包括并口和PCI总线。
(3)CPU如何进行设备的寻址?I/O端口的编址方式有哪两种?各有何特点?
CPU通过地址总线向系统总线发送地址信号,让系统总线连接的设备进行响应。设备通过地址识别电路判断是否是自己需要响应的地址,如果是,则进行数据传输;如果不是,则不做响应。CPU根据总线协议规定的访问方式,向设备发送读写命令和数据,设备根据命令进行相应的操作。
I/O端口的编址方式主要有两种:基于端口号编址和基于内存映射编址。
- 基于端口号编址:这种方式下,每个I/O设备都被赋予了一个唯一的端口号。程序每次需要与设备进行通信时,都需要指定设备的端口号。
- 基于内存映射编址:这种方式下,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 |