计算机系统课程作业

本文最后更新于:2022年5月27日 晚上

小班讨论

这是本人自己做的小班讨论的题目,放在了 ,里面还包含有部分操作系统导论的代码。

其中第几次小班讨论以英文字母区分,如第一次就是first.

没有传的就是我没做的

GitHub

课程作业

第一次课程作业网上容易找到答案,我就不放了。

第二次课程作业:

简单的放点题目:

第一题

有如下c语言程序,其中的H和J定义为一个常数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# include "stdio.h"

# define H ? //定义常数H

# define J ? //定义常数J


int array1[H][J];

int array2[J][H];


void f(int x, int y) {

array1[x][y] = x+2*y;

array2[y][x]=y-x*x;

}

int main( )

{

return 0;

}

我的解答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
一、
H=37,J=16
pushl %ebp
前两行压程序栈

movl %esp,%ebp

push %ebx
压 f 函数栈

movl 8(%ebp), %ecx
赋值 x

movl 12(%ebp), %edx
赋值 y

movl 12(%ebp), %eax
赋值 y

addl %eax, %eax
eax 自增为 2 倍(2y)

addl 8(%ebp), %eax
eax=eax+ecx x+2*y

sall $4, %ecx
ecx 的值左移 4 位 x*16

leal (%ecx,%edx), %edx
把 ecx+edx 的地址给 edx x*16+y 即 x 的系数 J=16

movl %eax, array1(,%edx,4)
把 eax 的值给 array1 的 edx* 4 位的地方 4*(x* 16+y)的地方=x+2* y,即 array1[x][y]=x+2*y

movl 12(%ebp), %edx
赋值 y

movl 8(%ebp), %ebx
赋值 x

movl 8(%ebp), %eax
赋值 x

imull 8(%ebp), %eax
eax=eax* eax x*x

movl 12(%ebp), %ecx
ecx=edx ecx 处=y

subl %eax, %ecx
ecx=ecx-eax y-x*x

movl %edx, %eax
eax=edx eax 处=y

sall $3, %eax
eax < < 3 相当于y < < 3 3 即是 J 的值

addl %edx, %eax
eax=eax+edx y< <3+y

sall $2, %eax
eax< <2 (y< <3+y)< <2

addl %edx, %eax
eax=edx+eax (y< <3+y)< <2+y

addl %ebx, %eax
eax=eax+ebx (y< <3+y)< <2+y+x 即 y 的系数 H=(8+1)*4+1=37

movl %ecx, array2(,%eax,4)
把 array2 的 4* eax 的地方赋值为 ecx 即 array2 的 4*eax 的地方=y-x *x 即 array2[x][y]=y-x*x

popl %ebx
出函数栈

popl %ebp
出栈

ret
结束程序

第二题

如下为一个c语言程序中的函数及其在32位系统下编译得到的汇编语言程序代码,请详细说明每条汇编语句的意义,并将这个函数补充完整。

我的解答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
二、

int aprod(int a[], int n) {

int i, x, y, z;

int r = 1;

for (i = 0; ( i< n-2 ); ( i+=3 )) {

( x=a[i] );

( y=a[i+1] );

( z=a[i+2] );

( r=r*x*y*z* );

}

for (; i < n; i++)

( r=a[i]*r );

return r;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
汇编分析:

aprod:

pushl %ebp //前两行压栈

movl %esp, %ebp //栈帧

subl $32, %esp //esp-32

movl $1, -20(%ebp) //ebp小20的位置放1 r=1

movl $0, -4(%ebp) //ebp小4的位置放0 i=0

jmp.L2 //无条件跳转到.L2

.L3:

movl -4(%ebp), %eax //eax=0=i

sall $2, %eax //eax=0*4=0

addl 8(%ebp), %eax //eax加上ebp大8的位置,即eax+=a[]

movl (%eax), %eax //eax=a[i]

movl %eax, -8(%ebp) //ebp小8的地方赋值为eax x=a[i]

movl -4(%ebp), %eax //eax=i=0

addl $1, %eax //eax=i+1=1,

sall $2, %eax //eax=4

addl 8(%ebp), %eax //eax加上ebp大8的位置 eax=4+a[]

movl (%eax), %eax //eax=a[i+1]

movl %eax, -12(%ebp) //ebp小12的位置变为eax y=a[i+1]

movl -4(%ebp), %eax //eax=ebp小4的位置 eax=i=0

addl $2, %eax //eax+=2 eax=2

sall $2, %eax //eax*=4 eax=8

addl 8(%ebp), %eax //eax+ebp大8的位置 eax=8+a[]

movl (%eax), %eax //eax=a[i+2]

movl %eax, -16(%ebp) //ebp小16的位置放eax z=eax=a[i+2]

movl -20(%ebp), %eax //eax=1=r

imull -8(%ebp), %eax //eax*ebp小8处的位置的值 eax=r *x

imull -12(%ebp), %eax //eax*ebp小12处的位置的值 eax=r *x *y

imull -16(%ebp), %eax //eax*ebp小16处的位置的值 eax=r *x *y *z

movl %eax, -20(%ebp) //ebp小20处的位置的值变为eax r=eax

addl $3, -4(%ebp) ebp小4处的位置的值加三 i=i+3

.L2:

movl 12(%ebp), %eax //eax被赋值为ebp大12的位置的值 eax=n,

subl $2, %eax //eax-2 eax=n-2

cmpl -4(%ebp), %eax //比较eax和ebp小4处的值谁大,小于跳到L3,大于等于跳到L4 即比较i和n-2的大小,i>n-2跳转到L3

jg.L3

jmp.L4

.L5:

movl -4(%ebp), %eax //eax=0=i

sall $2, %eax //eax*4

addl 8(%ebp), %eax //eax+大于ebp8的位置的值 即eax=0+a[]

movl (%eax), %eax //eax=a[i]

movl -20(%ebp), %edx //edx=1=r

imull %edx, %eax //eax*=edx 即eax=a[i]*r

movl %eax, -20(%ebp) //ebp小20处的位置的值等于eax r=eax

addl $1, -4(%ebp) //ebp小4处的位置的值+=1 i+=1

.L4:

movl -4(%ebp), %eax //eax=0

cmpl 12(%ebp), %eax //比较eax和比ebp大12处的位置的值,小于则跳转到L5

jl.L5

movl -20(%ebp), %eax //eax=ebp小20处的位置的值

leave //退出

ret

第三题

有如下C语言程序及在Ubuntu 32位系统下用gcc编译而得到的汇编代码,请详细解释每一条汇编指令的意义并将c语言程序补充完整。

我的解答:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
三、
#include <stdio.h>


int frac(int a)

{

if(a<2) return a*a;

return frac(a-2)+a;

}

int sum(int a,int b)

{

int c=frac(a+b);

return 2*c+b;

}

int main()

{

int i=10,j=6;

int k=sum(j-i,i++);

return 0;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
汇编代码:
frac:


pushl %ebp //压栈
movl %esp, %ebp //栈帧
subl $24, %esp //esp-24,开辟空间
cmpl $1, 8(%ebp) //比较1和a的大小,a>1则跳到L2
jg .L2

movl 8(%ebp), %eax //eax=a

imull 8(%ebp), %eax //eax*=eax,eax=a*a

jmp .L3 //无条件跳转到L3

.L2:

movl 8(%ebp), %eax //eax=a

subl $2, %eax //eax-=2 eax=a-2

movl %eax, (%esp) //esp的位置=eax=a-2

call frac //调用frac,此时由于esp的位置是a-2,因此相当于frac(a-2)

addl 8(%ebp), %eax //eax+=a,即eax=frac(a-2)+a

.L3:

leave //退出

ret

sum:

pushl %ebp //压栈

movl %esp, %ebp //栈帧

subl $40, %esp //esp-40开辟空间

movl 12(%ebp), %eax //eax=b

movl 8(%ebp), %edx //edx=a

addl %edx, %eax //eax+=edx,eax=b+a

movl %eax, (%esp) //eax给到esp

call frac //调用frac函数,同上面的那个frac,相当于frac(a+b)

movl %eax, -12(%ebp) //c=frac(a+b)

movl -12(%ebp), %eax //eax=c

addl %eax, %eax //eax+=eax,eax=2*c

addl 12(%ebp), %eax //eax+=b,eax=2*c+b

leave

ret

main:

pushl %ebp //压栈

movl %esp, %ebp //栈帧

andl $-16, %esp //esp和-16与运算

subl $32, %esp //esp-32开辟空间

movl $10, 20(%esp) //i=10

movl $6, 24(%esp) //j=6

movl 20(%esp), %eax //eax=10=i

movl 24(%esp), %edx //edx=6=j

subl %eax, %edx //edx=-4

movl 20(%esp), %eax //eax=10

addl $1, 20(%esp) //i=11

movl %edx, 4(%esp) //esp大于4处=-4

movl %eax, (%esp) //eax给到esp=10

call sum //调用sum,sum函数需要两个参数,这两个参数在上面,也就是sum(j-i,i++)

movl %eax, 28(%esp) //esp大于28处=10,即k=eax=sum(j-i,i++)

movl $0, %eax //eax=0

leave //退出

ret

第三次课程作业:

不是很想做硬件。。。

第四次

课本有答案