当前位置:文档之家› 最新复旦大学计算机体系结构期末考试B卷

最新复旦大学计算机体系结构期末考试B卷

(1)考虑下面这个for循环的汇编代码looper:pushl %ebpmovl %esp, %ebpsubl $16, %espmovl $0, -8(%ebp)movl $0, -4(%ebp)jmp .L2.L4:movl -4(%ebp), %eaxsall $2, %eaxaddl 12(%ebp), %eaxmovl (%eax), %eaxcmpl -8(%ebp), %eaxjle .L3movl -4(%ebp), %eaxsall $2, %eaxaddl 12(%ebp), %eaxmovl (%eax), %eaxmovl %eax, -8(%ebp).L3:addl $1, -8(%ebp)addl $2, -4(%ebp).L2:movl -4(%ebp), %eaxcmpl 8(%ebp), %eaxjl .L4movl -8(%ebp), %eaxleaveret根据以上的汇编代码,完成相应的for循环C程序代码(注意该程序有返回值)。

int looper(int n, int *a){int i;int x=0;for(i= 0 ; i<n //2分; i+=2 //2分){______________________________________if(a[i]>x)//2分x=a[i];// 2分x++;//1分}______________________________________return x;// 1分}(2)根据已有的结构(structure)和联合(union)的声明以及C函数void test(int i, s2 *bp)的IA32 汇编代码,推断出结构s1的完整声明和s2中CNT的值;之后再根据推断结果以及IA32汇编代码,推断补齐相应的C程序代码。

下面是要使用到的结构和联合的声明,函数void test(int i, s2 *bp)及其IA32 汇编代码。

struct s1 { struct s2 { union u1 {int left; struct s1 *h;s1 a[CNT]; struct s2 *i;int right; char j; }; union u1 b; };char c;};void test(int i, s2 *bp){int n=bp->left+bp->right;s1 *ap=&bp->a[i];ap->x[ap->idx]=n;}其IA32汇编代码为:test:pushl %ebpmovl %esp, %ebpsubl $16, %espmovl 12(%ebp), %eaxmovl (%eax), %edxmovl 12(%ebp), %eaxmovl 184(%eax), %eaxleal (%edx,%eax), %eaxmovl %eax, -4(%ebp)movl 12(%ebp), %eaxleal 4(%eax), %ecxmovl 8(%ebp), %edxmovl %edx, %eaxsall $2, %eaxaddl %edx, %eaxsall $2, %eaxleal (%ecx,%eax), %eaxmovl %eax, -8(%ebp)movl -8(%ebp), %eaxmovl (%eax), %edxmovl -8(%ebp), %eaxmovl -4(%ebp), %ecxmovl %ecx, 4(%eax,%edx,4)leaveret1. CNT=___9_____//2分2. 写出s1的完整声明。

____struct s1{int idx;//2分int x[4];//2分___}__________________________________________________________________________________________________________________3. 对于下面左边的每个IA32 汇编代码,请在右边补全相应的C程序代码。

(请注意下面的函数都需要返回值)A. proc1:pushl %ebpmovl %esp, %ebpmovl 8(%ebp), %eaxmovzbl 188(%eax), %eaxpopl %ebpret char proc1(struct s2 *x){______________________________ return x->b.j;(4分)______________________________ ______________________________ ______________________________ }B. proc2:pushl %ebpmovl %esp, %ebpsubl $16, %espmovl 8(%ebp), %eaxmovl 188(%eax), %eaxmovl (%eax), %eaxmovl %eax, -4(%ebp)movl 8(%ebp), %eaxmovl 188(%eax), %eaxmovl 184(%eax), %eaxaddl %eax, -4(%ebp)movl -4(%ebp), %eaxleaveretC. proc3:pushl %ebpmovl %esp, %ebpsubl $16, %espmovl 8(%ebp), %eaxmovl (%eax), %eaxmovl 188(%eax), %eaxmovzbl 192(%eax), %eaxmovb %al, -1(%ebp)movl 8(%ebp), %eaxmovl (%eax), %eaxmovzbl 188(%eax), %eaxandb %al, -1(%ebp)movzbl -1(%ebp), %eaxleaveret int proc2(struct s2 *x){______________________________int a = x->b.i->left;//2分a += x->b.i->right;//3分return a;(3分)____________________________________________________________ }char proc3(union u1 *x){______________________________char a = x->i->b.i->c;//2分a &= x->i->b.j//3分return a;(3分)______________________________ ______________________________ }(3)Pentium III的算术操作性能如下:考虑如下程序:int loop(int *a, int x, int n){int y=x*x;int i;for(i=0;i<n;i++){x=y*a[i];取i,取y,再发射,共3个时钟周期;这里没迭代。

return x*y;}}用GCC进行编译,得到如下汇编代码:.L2:movl %ecx,%eaximull (%esi,%edx,4),%eaxincl %edxcmpl %ebx,%edxjl .L21.每次循环需要的时钟周期数是多少?3.0//4分2.通过使用编译选项-funroll -loops,我们可以在编译时进行4路循环展开,此方法可以加快loop的运行,解释原因。

程序的循环次数变少,降低了循环的开销。

即减少了y和a[i]的load需要的1个时钟周期。

//6分(4)考虑如下一段程序:int counter=2;void handler(int sig){counter++;}int count(){signal(SIGCHLD, handler);int i, status;for(i=1; i<=2; i++){counter++;if(fork()>0){counter++;while (waitpid(-1,&status,0)>0);return counter;}counter+=i;}return counter;}int main(){printf("counter =%d\n", count());exit(0);}问:1. 程序是否总是有相同输出?是//6分2. 如果第一问答案为”是”,给出此固定输出,如果答案为”否”,则列出所有可能输出。

counter=7counter=7counter=5//4分(5)请写出一段代码,父进程利用fork()函数创建一个子进程之后挂起,子进程什么也不做,睡眠5s后通过kill函数发送SIGALRM信号给父进程,再睡眠3s,然后以状态1退出。

父进程在信号处理程序中,回收子进程,打印子进程的退出状态,之后以状态0退出。

注意程序中用到的系统调用函数不必进行错误检查,用到的头文件已经给出。

#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <signal.h>#include <stdio.h>void handler(int sig){int status;waitpid(-1,&status,0);printf("%d\n",WEXITSTATUS(status)); exit(0);}int main(){pid_t pid;signal(SIGALRM, handler);if(fork()==0){pid=getppid();sleep(5);kill(pid,SIGALRM);sleep(3);exit(1);}pause();}sigal()-handler()2分fork() 1分kill()1分waitpid() 1分sleep() 1分WEXITSTATUS 1分exit() 1分程序结构 2分(6)下面这个问题考察你如何将虚拟地址翻译成物理地址。

我们做出如下假设:这个存储器是按字节寻址的;存储器访问是针对1字节的字的(不是4字节的字);虚拟地址是16位长的;1. (1) 下面需要你描述虚拟地址的格式。

请在表格下方标注出下列符号的表示范围。

如果其中有符号在本题中不需要用到,请不要标注。

VPO 虚拟页面偏移VPN 虚拟页号TLBI TLB索引号TLBT TLB标记15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0VPN: [15-10] VPO: [9-0]//2分TLBT: [15-11] TLBI: [10]//1分(2) 下面需要你描述物理地址的格式。

相关主题