csapp半期总结

版权声明:版权所有,欢迎相互学习与交流 https://blog.csdn.net/qq_42229034/article/details/84679762

这是一篇基调凄凉的文章,因为笔者半期考试没上我们转专业班班平。

准确来说,整个半期考试都考得很差,是时候反思并且改进学习方法了。

原因一方面是对条件码极度不熟悉,这个我觉得并不重要的东西反而每个题都在考,一方面是感觉知识还没有融汇,另一方面是老师出了点超纲的数组题(我菜是原罪...)。这篇水文的主要目的是根据考试犯错的题,排一下知识盲点解决一下上半学期遗留的问题。最重要的是知识还没融会贯通,这是原罪。还有想吐槽一下考试用ppt呈现题目但是不发卷子,这个就非常恶心了。这篇文章旨在就一些错误进行反思和总结,个人向而已:

零、关于标志位和整数加减法的东西:

      这就很难受了,我没有怎么看第二章的东西,并且标志位也没记住...老师不挂我挂谁?

      CF:进位标志,最近的操作让最高位产生了进位,可用来检查无符号数的溢出。

      OF:溢出标志,最近的操作让一个补码溢出了,要么是正溢出,要么是负溢出。

      ZF:得零标志,最近的操作的结果得零,则ZF=1;

      SF:是负数(符号位signal为1)标志,最近的操作得结果得到一个负数。

     楼下是笔者找的某一位博主总结的一幅图,我觉得很ok的:

è¿éåå¾çæè¿°

对于整数加法:

1.x与y都是无符号数,w位的(一个w位的无符号数,它最大时11111...1(w个1),值是2^w -1),那么0<=x,y<=2^w -1,那么如果x+y没有超过2^w,那么该是多少是多少,如果溢出了,那么我们就取mod 2^w.

2.x,y都是有符号数,w位的(一个w位的有符号数,它最大是0111.....1(w-1个1),值是2^(w-1) -1),最小是10000...0(w-1个0),值是-2^(w-1) ),那么就有正溢出和负溢出了。

一、浮点数表示

y=0xd3e4c000的十进制数。(题中说了y是浮点数,我...我没看到,虽然可能即使看到了,我考试的时候也忘了)

     我们转化为二进制串,y=1*101   0011   1* 110    0100    1100    0000    0000    0000.【*表示字段的分类】对于32位4字节的float型,第一位是符号位,1表示是负数,然后我们计算阶码部分,E=e-Bias,BIas=2^(阶码位数-1)-1,一般的float型是1,8,23这种字段结构,所以float的Bias是127;double型是1,11,52这种字段结构,其偏置Bias=1023.所以本题中,阶码的值E=e-BIas=(101 0011 1)2  -127=(40)decimal。然后我们计算尾数M,M一般等于1+f(隐含1开头)如果阶码全零则M=f。所以本题答案是 V=(-1)* 2^40 * (1+1/2+1/4+1/32+...)。

二、一道综合题:

1.add是自增运算,考试的时候忘记加自身了

  首先,%rdi+%rcx=0x1020,再加便宜0x8,得到地址0x1028,这个地址中的值是0xca50,然后我们进行值与值之间的加法运算,将值0xca50加上值0xaa,就得到了0xcafa

2.testq %rdx %rdx,%rdx内的值是0xaa不等于zero,所以ZF=0。然后cmovne也因为(不相等/非零),所以要送数。

3.%rdi和%rsi加起来的地址加偏置6得到0x1009,因为条件码ZF=0,我们从中取得按小端(低数位存在前面,高数位存在后面的规则)取出8个字节(%rax),0x1008--89,0x1009--67,0x100a--05,0x100b--00,0x100c--00,0x100d--00,0x100e--00,0x100f--00,0x1010--22,我们取出八个内存64位,分别是0x1009--67,0x100a--05,0x100b--00,0x100c--00,0x100d--00,0x100e--00,0x100f--00,0x1010--22,那么%rax的值就是0x2200000000000567。

4.我们从%esi中自减立即数Imm=4,得到-1,由于%esi是四字节32位,十六进制数四位为一个数位,所以一共会有8位(16进制),而-1用十六进制表示,就是0xffffffff,这是因为0xffffffff=-1*最高权+1*次高权+1*次次高权+....= - 1.(简单的等比数列)。

5.我们将%ebx内的值0xc,即1100,sall,左移动29位,那么我们从第一位到第32位中,是第三位移到32位的(32-3=29),所以第三十二位(最高的标志位)得到1,代表“是负数”,那么SF=1,命题为真。(考试的时候,我数错了!!!)

6.当移动后,我们得到的是0x1000....此处省略一系列个0,表示的是=-1*最高位位权=(可以是)INT_MIN,然后我们进行cmpl $2 %ebx操作,在int-min基础上减去2,又回到一个正数,这个正数是int-max-1,那么发生了负溢出,我们置OF=1.然后因为这种compare操作只是比较不改变,所以%ebx该是多少是多少不改变。

7、这个题体现了计算机能够分段送数的特性,所以我们将末尾16位两字节送入%ax中,%rax其余位不变,但是注意到%rax在前面的运算中已经改变过值了,所以只用把低16位改变成0x0088,前面不变就行。

8.js表示“负数就跳转”,由于我们最后得到(相减来判断)一个正数,所以后者“大”,所以不是负数,所以不跳转。

另外,加括号就是取地址,leaq我们单独说。

leaq:加载有效地址,看似是从内存里面读数据到寄存器中,其实压根就没有引用内存,根本就与有效地址计算无关,其本质是mov指令的变形,对source操作后送入destination之中而已。

三、分析一个汇编,填空:

fabe:
    movl $0,%eax
    jmp .L2

.L5 movslq %eax,%r8
    leaq (%rdi,%r8,4),%rdx
    movl (%rdx),%ecx
    cmpl %ecx,%eax
    jne .L3
    addl %eax,%ecx
    movl %ecx,(%rdx)
    ret

.L3  leaq 4(%rdi,%r8,4),%r8
    movl (%r8),%r9d
    movl %r9d,(%rdx)
    movl %ecx,(%r8)
    addl $1,%eax

.L2 cmpl %esi,%eax
    jl .L5
    movl $-1,%eax
    ret
//源码:
int fabe(int *a,int m)
{
    int i,temp;
    for(i=0;i<m;i++)
    {
        temp=a[i];
        if(i==temp)
        {
            ?; //temp+=i;
            return ?; //return i; gcc调用约定%eax习惯上作为返回值
        }
        else
        {
          ?;//a【i】=a【i+1】;
          ?;//a【i+1】=temp;
        }
    }
    return ?; //-1
    
}

最后,想给自己说,这套题回头看如此简单,考的不好不是一件羞耻的事情,这是暴露自己问题的机会,后面一个月要加油了,争取期末总评还有90+!

期末考完了,估计可能上不了90了,我有些哽咽。

猜你喜欢

转载自blog.csdn.net/qq_42229034/article/details/84679762
今日推荐