第二章 习题解答

更新时间:2024-05-31 12:07:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第二章习题解答

1. 计算机指令由哪两部分构成?他们分别表示什么含义?

解答:计算机的指令通常由两个部分构成:操作码和操作数。操作码指明计算机应该执行什么样的操作,而操作数则指出该操作处理的数据或数据存放的地址。 2. 现代计算机系统存在哪两种类型的指令集?它们分别有什么特点?

解答:

复杂指令集计算机(CISC)和精简指令集计算机(RISC) CISC结构指令集的特点是:

①指令系统复杂庞大,指令数目一般多达2、3百条。 ②寻址方式多 ③指令格式多 ④指令字长不固定 ⑤可访存指令不加限制

⑥各种指令使用频率相差很大 ⑦各种指令执行时间相差很大 RISC结构指令集的特点是:

①精简了指令系统,流水线以及常用指令均可用硬件执行;

②采用大量的寄存器,使大部分指令操作都在寄存器之间进行,提高了处理速度; ③每条指令的功能尽可能简单,并在一个机器周期内完成; ④所有指令长度均相同;

⑤只有Load和Store操作指令才访问存储器,其它指令操作均在寄存器之间进行;

3. 假定以下C语句中的所有变量为32位的寄存器,请分别采用MIPS汇编指令实现其功

能:

a)f=g+h+i+j; b)f=g+(h+5); c)f=f+f+i; d)f=g+(j+2); 解答:灵活使用加法算术运算指令 a) add f, g,h addf,f,i addf,f,j

b) addi f,h,5 addf,f,g c) addf,f,f addf,f,j d) addi f,j,2 addf,f,g 4. 假定以下MIPS汇编指令的所有寄存器都已经在C语言中定义,请分别采用相应的C语

句实现其功能: a)add f,g,h b)add f,f,h c) add f,f,1 d)sub f,$0,f

addf,g,h addi f,f,1 解答:a) f=g+h; b) f=f+h; c)f=g+h; d) f=1-f;

5. 假定字变量f,g,h,i,j分别对应寄存器$s0,$s1,$s2,$s3,$s4,并且字数组A和B的起始地址分

别存放在寄存器$s6,$s7中,请分别采用MIPS汇编指令实现其功能: a) f=g+h+B[4]; b) f=g-A[B[4]]; c) f=g+h+B[1]; d) f=A[B[g]+1]; 解答:a) lw $t0,16($s7) b) lw $t0,16($s7) add $s0,$s1,$t0 sll $t0,$t0,2 add $s0,$s2,$s0 add $t1,$s6,$t0 lw $t2,0($t1) sub $s0,$s1,$t2 c) lw $t1,4($s7) d)sll $s1,$s1,2 add $s0,$s1,$t0 add $t0,$s7,$s1 add $s0,$s0,$s2 addi $t0,$t0,1 sll $t0,$t0,2 add $t1,$t0,$s6 lw $s0,0($t1)

6. 假定变量f,g,h,i,j分别对应寄存器$s0,$s1,$s2,$s3,$s4,并且字数组A和B的起始地址分别

存放在寄存器$s6,$s7中,请分别采用相应的C语句实现以下汇编指令序列的功能: a) add $s0,$s0,$s1 b) lw $s0,4($s6)

add $s0,$s0,$s2 add $s0,$s0,$s3 add $s0,$s0,$s4 c) add $s0,$s0,$s1 d) addi $s6,$s6,-20

add $s0,$s3,$s2 add $s6,$s6,$s1 add $s0,$s0,$s3 lw $s0,8($s6) 解答:a)f=f+g+h+i+j; b)f=A[1] c) f=h+i+i; d) f=A[g/4-5+2]

7. 分别指出以下各指令序列执行后的结果,假定$t0=0x55555555,$t1=0x12345678

a) sll $t2,$t0,4 b) sll $t2,$t0,4 c) srl $t2,$t0,3

and $t2,$t2,$t1 andi $t2,$t2,-1 andi $t2,$t2,0xffef d) sll $t2,$t0,1 e) sll $t2,$t0,1 or $t2,$t2,$t1 andi $t2,$t2,0x00f0

解答:a) $t2=0x10145450 b)$t2=0x55555550 c) $t2=0xaaaa

d) $t2=0xbabefefa e)$t2=0xa0

8. 采用汇编指令分别针对不同的i,j值组合完成将$t0中的field域填充到$t1中相对应的

field域中,且$t1的其余位都清0.$t0的构成如下: 31 i+1 xx i j+1 field j 0 xx $t1的构成分别如a),b)所示:

a) 31 15+i-j 0000000….. 14+i-j 15 field 14 0 00 0000 0000 0000 i-j-1 0 field b) 31 i-j 0000….. 1) i=7,j=2 2)i=24,j=5 解答:1)a)andi $s0,$t0,0xf8 b)andi $s0,$t0,0xf8 sll $t1,$s0,12 slr $t1,$s0,3

2) a) andi $s0,$t0,0x1fe0 b)andi $s0,$t0,0x1fe0

sll $t1,$s0,12 slr $t1,$s0,6

9. 分别针对以下两个汇编指令段回答问题: 指令段a) loop : slt $t2,$0,$t1 bne $t2,$0,else j done else :addi $s2,$s2,2 addi, $t1,$t1,-1 j loop done:

指令段b) loop : addi $t2,$0,0xa Loop2: addi $s2,$s2,2 addi $t2,$t2,-1 bne $t2,$0,loop2 addi $t1,$t1,-1 bne $t1,$0,loop done: 问题:1)若指令执行前$t1=10,$s2=0,那么在分别执行以上指令序列后,$s2的值为多少? 2)假设$s1,$s2,$t1,$t2分别对应变量A,B,i和temp,那么对应以上汇编指令序列的C语句分别是什么? 3)如果$t1初始化为N,针对以上指令序列分别需要执行多少条指令? 解答:1) a)$s2=0x14 2*$t1=20 b)$s2=0xc8 2*10*$t1 2) a) while (i>0){ b)do { B=B+2; for(temp=0xa;temp!=0;temp--) i--; B=B+2; } i--; } while(i!=0)

3)当N〉0时 a)循环体内指令执行的次数为N,循环体共3条指令,执行次数为3N,循环条件判断指令执行的次数为N+1,共2条指令,执行次数为2(N+1),最后执行一次退出循环指令,因此共执行5N+3条指令

b)双重循环,内循环每次执行3*10条指令,外循环一次除了内循环之外还有另外3条指令,因此外循环一次共执行33条指令,总共执行33N条指令

当N<=0时,a) 仅执行判断及退出指令,共3条 b) N=0,将执行33*232条指令;N<0,将执行33*(232+N)条指令

10. 2.10将以下C语句转换为MIPS汇编指令序列,假设变量a,b,i,j分别对应寄存器

$s0,$s1,$t0,$t1, $s2保存着数组D的起始地址。 a)for(i=0;i<10;i++) b)while(a<10) {

a+=b; D[a]=b+a; a+=1; } 解答: 1)

loop: slti $s3,$t0,10 #$s3=i<10?1:0 beq $s3,$0,exit #$s3=0,exit add $s0,$s0,$s1 #a+=b addi $t0,$t0,1 #i++ j loop exit: 2)

loop: slti $s3,$s0,10 #$s3=a<10?1:0 beq $s3,$0,exit

add $s4,$s0,$s1 #$s4=a+b sll $t2,$s0,2 #数组偏移地址 add $t4,$s2,$t2

sw $s4,0($t4) #存储数组元素 addi $s0,$s0,1 j loop exit:

11. 以下汇编语言程序段实现斐波那契(Fibonacci)数的计算,其输入的整数保存在$a0中,

输出结果保存在$v0中。但是存在一些错误,请修正其中的错误。并画出当输入数字4时,该程序段每次被调用时栈的变化情况。 FIB: addi $sp,$sp,-12 sw $ra,0($sp) sw $s1,4($sp) sw $a0,8($sp) slti $t0,$a0,1 beq $t0,$0,L1 addi $v0,$a0,$0 j EXIT L1: addi $a0,$a0,-1 jal FIB addi $s1,$v0,$0 addi $a0,$a0,-1

jal FIB

add $v0,$v0,$s1 Exit:lw $ra,0($sp) lw $s1,4($sp) lw $a0,8($sp)

addi $sp,$sp,12 jr $ra

解答:斐波那契数列指的是这样一个数列:0,1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, … 斐波那契(Fibonacci)数的计算C语言函数原型n=0开始 int fib(intn,int f) { if(n==0) f=0;

elseif(n==1) f=1;

else

f=fib(n-1,f)+fib(n-2,f);

return f; } 正确的错误的

FIB: addi $sp,$sp,-12 FIB: addi $sp,$sp,-12 sw $ra,0($sp) sw $ra,0($sp) sw $s1,4($sp) sw $s1,4($sp) sw $a0,8($sp) sw $a0,8($sp) slti $t0,$a0,2 slti $t0,$a0,1 beq $t0,$0,L1 beq $t0,$0,L1 add $v0,$a0,$0 addi $v0,$a0,$0 ;N=0,1直接得到结果 j Exit j EXIT L1: addi $a0,$a0,-1 L1: addi $a0,$a0,-1 jal FIB jal FIB add $s1,$v0,$0 addi $s1,$v0,$0 ;暂存n-1的结果 addi $a0,$a0,-1 addi $a0,$a0,-1

jal FIB jal FIB add $v0,$v0,$s1 add $v0,$v0,$s1 ;将n-1与n-2的结果相加 Exit:lw $ra,0($sp) Exit:lw $ra,0($sp) lw $s1,4($sp) lw $s1,4($sp) lw $a0,8($sp) lw $a0,8($sp) addi $sp,$sp,12 addi $sp,$sp,12 jr $ra jr $ra

[00400024] 34040004 ori $4, $0, 4; 1: li $a0,4 [00400028] 0c10000c jal 0x00400030 [FIB]; 2: jal FIB [0040002c] 0810001f j 0x0040007c [exit]; 3: j exit

[00400030] 23bdfff4 addi $29, $29, -12; 4: addi $sp,$sp,-12 [00400034] afbf0000 sw $31, 0($29); 5: sw $ra,0($sp) [00400038] afb10004 sw $17, 4($29); 6: sw $s1,4($sp) [0040003c] afa40008 sw $4, 8($29); 7: sw $a0,8($sp) [00400040] 28880003 slti $8, $4, 2; 8: slti $t0,$a0,2

[00400044] 11000003 beq $8, $0, 12 [L1-0x00400044]; 9: beq $t0,$0,L1 [00400048] 00801020 add $2, $4, $0; 10: add $v0,$a0,$0 [0040004c] 0810001a j 0x00400068 [Exit]; 11: j Exit

[00400050] 2084ffff addi $4, $4, -1; 12: addi $a0,$a0,-1 [00400054] 0c10000c jal 0x00400030 [FIB]; 13: jal FIB [00400058] 00408820 add $17, $2, $0; 14: add $s1,$v0,$0 [0040005c] 2084ffff addi $4, $4, -1; 15: addi $a0,$a0,-1 [00400060] 0c10000c jal 0x00400030 [FIB]; 16: jal FIB [00400064] 00511020 add $2, $2, $17; 17: add $v0,$v0,$s1 [00400068] 8fbf0000 lw $31, 0($29); 18: lw $ra,0($sp) [0040006c] 8fb10004 lw $17, 4($29); 19: lw $s1,4($sp) [00400070] 8fa40008 lw $4, 8($29); 20: lw $a0,8($sp) [00400074] 23bd000c addi $29, $29, 12; 21: addi $sp,$sp,12 [00400078] 03e00008 jr $31; 22: jr $ra

$sp $sp

Fib 函数嵌套调用栈变化过程 7ffff9c8 00000004($a0) 7ffff9c4 7ffff9c0 00000000($s1) 0040002c(&j 0x0040007c [exit]) 首次调用fib(4) $a0=4 7ffff9c8 00000004($a0) 7ffff9c4 7ffff9c0 7ffff9bc 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) 嵌套调用fib(3) $a0=3 $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) 7ffff9b0 00000002($a0) 7ffff9ac 00000000($s1) 7ffff9a8 00400058(&add $17, $2, $0) 嵌套调用fib(2) $a0=2

7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) 7ffff9b0 00000002($a0)

$sp 7ffff9ac 00000000($s1) 7ffff9a8 00400058(&add $17, $2, $0) 7ffff9a4 00000001($a0) 7ffff9a0 00000000($s1) 7ffff99c 00400058(&add $17, $2, $0) 嵌套调用fib(1) $a0=1 $sp

7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) 7ffff9b0 00000002($a0) 7ffff9ac 00000000($s1) 7ffff9a8 00400058(&add $17, $2, $0) fib(1)返回执行add $s1,$v0,$0前 $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) 7ffff9b0 00000002($a0) 7ffff9ac 00000000($s1) 7ffff9a8 00400058(&add $17, $2, $0) 7ffff9b0 00000000($a0) 7ffff9ac 00000001($s1) 7ffff9a8 00400064(&add $2, $2, $17) 嵌套调用fib(0) $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) 7ffff9b0 00000002($a0) 7ffff9ac fib(0)返回

00000000($s1) 7ffff9a8 00400058(&add $17, $2, $0)

$sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) fib(2)返回,执行add $s1,$v0,$0前 $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) 7ffff9b0 00000001($a0) 7ffff9ac 00000001($s1) 7ffff9a8 00400064(&add $17, $2, $0) fib(2)返回,再次执行jal FIB后,此时$a0=1 $s1=1 $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000003($a0) 7ffff9b8 00000000($s1) 7ffff9b4 00400058(&add $17, $2, $0) fib(2)返回 $pc=00400064 $sp 7ffff9c8 7ffff9c4 7ffff9c0 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) fib(3)返回,执行add $s1,$v0,$0前 $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000002($a0) 7ffff9b8 00000002($s1) 7ffff9b4 00400064(&add $17, $2, $0) fib(3)返回,再次执行jal FIB(2) 后,此时$a0=2 $s1=2

7ffff9c8 7ffff9c4 7ffff9c0 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit])

$sp 7ffff9bc 00000002($a0) 7ffff9b8 00000002($s1) 7ffff9b4 00400064(&add $17, $2, $0) 00000001($a0) 00000002($s1) 00400058(&add $17, $2, $0) fib(3)返回,再次执行jal FIB (1)后,此时$a0=1 $s1=2 $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000002($a0) 7ffff9b8 00000002($s1) 7ffff9b4 00400064(&add $17, $2, $0) fib(3)返回执行add $s1,$v0,$0前 $sp 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000002($a0) 7ffff9b8 00000002($s1) 7ffff9b4 00400064(&add $17, $2, $0) 00000000($a0) 00000001($s1) 00400064(&add $17, $2, $0) fib(3)返回,再次执行jal FIB (0)后,此时$a0=0 $s1=3 7ffff9c8 7ffff9c4 7ffff9c0 7ffff9bc 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) 00000002($a0) 7ffff9b8 00000002($s1) 7ffff9b4 00400064(&add $17, $2, $0) fib(3)返回中的jal FIB (0)返回, 7ffff9c8 7ffff9c4 7ffff9c0 00000004($a0) 00000000($s1) 0040002c(&j 0x0040007c [exit]) fib(3)返回中的jal FIB (1)返回 fib(4)返回,栈恢复

12.若PC=0x00000000, 请分析是否可以仅采用条件跳转指令或无条件跳转指令跳转到下表所示地址?若能,分别需要采用多少条跳转指令? 跳转地址 条件跳转次数 无条件跳转次数

a. 0x00001000 b. 0xFFFC0000 1(正向跳转) 3(负向跳转) 1 否 解答:条件跳转指令中的立即数是16位符号数,其取值范围为-215~215-1, 新的PC的值=PC的原始值+16位立即数*4

因此当跳转指令的PC=0时,实际上PC的原始值已经变为4,一次正向跳转可跳转到的地址范围为:0x00000004~0x00020000 ,一次负向跳转可跳转到的地址范围为0xFFFE0004~0x0, 当跳转到0xFFFE0004,再次最远距离的跳转将跳转到0xFFFC0008,此地址仍然大于0xFFFC0000,因此还需要再进行一次跳转,共需跳转3次。

无条件跳转由于无法改变PC的最高4位,因此a)可以实现,b)无法实现。

13.利用MIPS汇编语言编程实现以下算式功能,并将结果输出到屏幕中。

1)通过键盘输入两个字类型的10进制数据,并且将它们的和、差以10进制形式输出到屏幕上

2)通过键盘输入两个字类型的16进制数据,并且将它们的和、差以16进制形式输出到屏幕上

3)分别对两个半字类型的符号数数组进行从大到小的排序,要求采用子程序实现单一数组数据的排序,主程序调用子程序分别对两个数组排序,并且分别将结果输出到屏幕上。

解答:1)2)主要考察系统功能调用的熟悉程度,由于QTspim可以直接支持10进制整数的输入输出,因此1)可以直接进行输入输出,但是2)需要进行转换,字符串到16进制以及16进制到字符串的转换。

1)程序源码: .data prompt: .asciiz \

sumresult: .asciiz \定义提示信息 difresult: .asciiz \.text main: li $v0,4

la $a0,prompt syscall #输出提示信息 li $v0,5 syscall #输入十进制数 add $s0,$v0,$0 #暂存输入结果 li $v0,4

la $a0,prompt syscall #输出提示信息 li $v0,5 syscall #输入十进制数 add $s2,$s0,$v0 #暂存和的结果 sub $s1,$s0,$v0 li $v0,4

la $a0,sumresult

syscall

#输出提示信息

bgez $t0,else # question (f) sub $t7,$zero,$t0 j exit

else: add $t7,$zero,$t0 exit:

j test # question (g) loop: add $s1,$s1,$t0 addi $t2,$t2,4 lw $t0,0($t2)

test: bne $t0,$zero,loop exit1:

li $t1,99 # question (h) j test1

loop1: add $v0,$v0,$t1 addi $t1,$t1,-1 test1: bgtz $t1,loop1 exit2: li $t0,1 # intipowr_for(int x, unsigned p) j test2

loop2: andi $s1,$s2,1 beq $s1,$zero,mullabel mult $t0,$t1 mflo $t0

mullabel:mult $t1,$t1 mflo $t1 srl $s2,$s2,1

test2: bne $s2,$zero,loop2 exit3:

本文来源:https://www.bwwdw.com/article/ht06.html

Top