深入理解计算机系统——课程作业2

深入理解计算机系统——课程作业2

简介

五一放假还有作业。。。

课程作业2共有三个题,都是分析汇编代码

第一题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//include "stdio.h"

//define H ? //定义常数H //H=37
//define J ? //定义常数J //J=16

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;
}

Ubuntu 32位系统下经过gcc汇编后,得到的函数f汇编代码如下:

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
f:
pushl %ebp //ebp入栈
movl %esp, %ebp //ebp设为现在的帧指针
pushl %ebx //ebx入栈
movl 8(%ebp), %ecx //ecx= M(8+ebp)=x
movl 12(%ebp), %edx //edx= M(12+ebp)=y
movl 12(%ebp), %eax //eax= M(12+ebp)=y
addl %eax, %eax //eax=2*eax=2*y
addl 8(%ebp), %eax //eax= M(8+ebp)+eax=x+2*y
sall $4, %ecx //ecx=ecx*16=16*x
leal (%ecx,%edx), %edx //edx= ecx+edx =16*x+y,so J=16
movl %eax, array1(,%edx,4) //array1[edx]=eax
movl 12(%ebp), %edx //edx=M(12+ebp)=y
movl 8(%ebp), %ebx //ebx=M(8+ebp)=x
movl 8(%ebp), %eax //eax=M(8+ebp)=x
imull 8(%ebp), %eax //eax=eax*M(8+ebp)=x*x
movl 12(%ebp), %ecx //ecx=M(12+ebp)=y
subl %eax, %ecx //ecx=ecx-eax=y-x*x
movl %edx, %eax //eax=edx=y
sall $3, %eax //eax=eax*8=8*y
addl %edx, %eax //eax=eax+edx=8*y+y
sall $2, %eax //eax=eax*4=9*y*4
addl %edx, %eax //eax=edx+eax=36*y+y
addl %ebx, %eax //eax=ebx+eax=37*y+x,so H=37
movl %ecx, array2(,%eax,4) //array2[eax]=ecx=y-x*x
popl %ebx //ebx出栈
popl %ebp //ebp出栈
ret

请分析每一行汇编代码的意义,并给出常数HJ的值。(20.0分)

第二题

如下为一个c语言程序中的函数及其在32位系统下编译得到的汇编语言程序代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
int aprod(int a[], int n) {
int i, x, y, z;
int r = 1;
for (i = 0; ( 1 ); ( 2 )) { //i<(n-2) i+=3
3 ); //x=a[i]
4 ); //y=a[i+1]
5 ); //z=a[i+2]
6 ); //r=r*x*y*z
}
for (; i < n; i++)
7 ); //r=a[i]*r
return r;
}

在32位系统中用gcc编译后,函数aprod对应的汇编语言程序代码如下:

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
aprod:
pushl %ebp //ebp入栈
movl %esp, %ebp //ebp设为现在的帧指针
subl $32, %esp //esp=esp-32,预留32字节给函数临时变量
movl $1, -20(%ebp) //r=M(ebp-20)=1
movl $0, -4(%ebp) //i=M(ebp-4)=0
jmp .l2 //无条件跳转到.l2

.l3:
movl -4(%ebp), %eax //eax=M(ebp-4)=i
sall $2, %eax //eax=eax*4=i*4
addl 8(%ebp), %eax //eax=eax+M(8+ebp)=4i+a[]
movl (%eax), %eax //eax=M(eax)=a[i]
movl %eax, -8(%ebp) //x=M(ebp-8)=eax=a[i]
movl -4(%ebp), %eax //eax=M(ebp-4)=i
addl $1, %eax //eax=eax+1=i+1
sall $2, %eax //eax=eax*4=4*(i+1)
addl 8(%ebp), %eax //eax=M(8+ebp)=4*[i+1]+a[]
movl (%eax), %eax //eax=M(eax)=a[i+1]
movl %eax, -12(%ebp) //y=M(ebp-12)=eax=a[i+1]
movl -4(%ebp), %eax //eax=(ebp-4)=i
addl $2, %eax //eax=eax+2=i+2
sall $2, %eax //eax=eax*4=4*(i+2)
addl 8(%ebp), %eax //eax=eax+M(8+ebp)=a[]+4*(i+2)
movl (%eax), %eax //eax=M(eax)=a[i+2]
movl %eax, -16(%ebp) //z=M(-16+ebp)=eax=a[i+2]
movl -20(%ebp), %eax //eax=M(-20+ebp)=r
imull -8(%ebp), %eax //eax*=M(-8+ebp)=r*x
imull -12(%ebp), %eax //eax*=M(-12+ebp)=r*x*y
imull -16(%ebp), %eax //eax*=M(-16+ebp)=r*x*y*z
movl %eax, -20(%ebp) //r=M(-20+ebp)=eax=r*x*y*z
addl $3, -4(%ebp) //i=M(-4+ebp)+=3=i+3

.l2:
movl 12(%ebp), %eax //eax=M(12+ebp)=n
subl $2, %eax //eax=eax-2=n-2
cmpl -4(%ebp), %eax //compare eax=n-2 with M(ebp-4)=i
jg .l3 //eax=n-2 > M(ebp-4)=i则跳转.l3
jmp .l4 //无条件跳转.l4

.l5:
movl -4(%ebp), %eax //eax=M(-4+ebp)=i
sall $2, %eax //eax=eax*4=4*i
addl 8(%ebp), %eax //eax=eax+M(8+ebp)=a[]+4*i
movl (%eax), %eax //eax=M(eax)=a[i]
movl -20(%ebp), %edx //edx=M(-20+ebp)=r
imull %edx, %eax //eax=eax*edx=a[i]*r
movl %eax, -20(%ebp) //r=M(-20+ebp)=eax=a[i]*r
addl $1, -4(%ebp) //i=M(-4+ebp)+1

.l4:
movl -4(%ebp), %eax //eax=M(-4+ebp)=i
cmpl 12(%ebp), %eax //compare eax=i with M(12+ebp)=n
jl .l5 //eax=i < M(12+ebp)=n则跳转
movl -20(%ebp), %eax //eax=M(-20+ebp)=r,返回值为r
leave
ret

请详细说明每条汇编语句的意义,并将这个函数补充完整。(40.0分)

第三题

如下为一个c语言程序中的函数及其在32位系统下编译得到的汇编语言程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//incl  ude <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(_______,______); //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
frac:
pushl %ebp //ebp入栈
movl %esp, %ebp //ebp=esp,设为当前的帧指针
subl $24, %esp //esp=esp-24,预留24字节给临时变量
cmpl $1, 8(%ebp) //compare a=M(8+ebp) with 1
jg .l2 //a=M(8+ebp) > 1则跳转到.l2
movl 8(%ebp), %eax //eax=M(8+ebp)=a
imull 8(%ebp), %eax //eax*=M(8+ebp)=a*a
jmp .l3 //无条件跳转.l3

.l2:
movl 8(%ebp), %eax //eax=M(8+ebp)=a
subl $2, %eax //eax=eax-2=a-2
movl %eax, (%esp) //M(esp)=eax=a-2
call frac //递归fun(a-2)
addl 8(%ebp), %eax //eax=eax+M(8+ebp)=fun(a-2)+a

.l3:
leave
ret

sum:
pushl %ebp //ebp入栈
movl %esp, %ebp //ebp=esp,设为现在的栈指针
subl $40, %esp //esp=esp-40,预留40字节给临时变量
movl 12(%ebp), %eax //eax=M(ebp+12)=b
movl 8(%ebp), %edx //edx=M(ebp+8)=a
addl %edx, %eax //eax=eax+edx=a+b
movl %eax, (%esp) //M(esp)=eax=a+b
call frac //调用frac(a+b)
movl %eax, -12(%ebp) //c=M(ebp-12)=eax=frac(a+b)
movl -12(%ebp), %eax //eax=M(ebp-12)=c
addl %eax, %eax //eax=2*eax=2*c
addl 12(%ebp), %eax //eax=eax+M(ebp+12)=2*c+b
leave
ret

main:
pushl %ebp //ebp入栈
movl %esp, %ebp //ebp设为现在的栈指针
andl $-16, %esp //esp=esp & 0xfffffff0
subl $32, %esp //esp=esp-32,预留32位字节给临时变量
movl $10, 20(%esp) //i=M(20+esp)=10
movl $6, 24(%esp) //j=M(24+esp)=6
movl 20(%esp), %eax //eax=M(20+esp)=i
movl 24(%esp), %edx //edx=M(24+esp)=j
subl %eax, %edx //edx=edx-eax=j-i=-4
movl 20(%esp), %eax //eax=M(20+esp)=i=10
addl $1, 20(%esp) //i=M(20+esp)+1=11
movl %edx, 4(%esp) //M(4+esp)=edx=-4
movl %eax, (%esp) //M(esp)=eax=10
call sum //调用sum(j-i,i++)
movl %eax, 28(%esp) //k=M(28+esp)=eax,将sum函数返回值赋给k
movl $0, %eax //eax=0, return 0
leave
ret

请详细说明每条汇编语句的意义,并将这个函数补充完整。(40.0分)

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021 Sung
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信