lili对《Computer Systems》的笔记(2)

lili
lili (Hacking)

读过 Computer Systems

Computer Systems
  • 书名: Computer Systems
  • 作者: Randal E. Bryant/David R. O'Hallaron
  • 副标题: A Programmer's Perspective(Edition 2)
  • 页数: 1000
  • 出版社: Prentice Hall
  • 出版年: 2008-3
  • 第100页
    检测溢出的一种方法。
    
    /*同级数相乘复制给一个比他大2倍一个变量,再把变量裁剪到于乘书同级。比较是否相同*/
    test_voerflowe(int a,int b) {
    long long int asize = a * (long long int)b ;
    int result = asize ;
    if result == asize)
    return no_overflowe ;
    else 
    return overfolow;
    }
    
    
    2.
    在C中用a == b检测两是否相同时,==不考虑a,b的符号,也就是说
    	int c =  0xf0001122 ;
    	unsigned d = 0xf0001122 ;
            if (c == d)
                true
    
    3. Tmin x = -x = 0x800...0
    ux * uy = x*y
    -y = ~y +1 -> ~y = -y-1
    4对于位移操作的注意
    在C中 对于有符号和无符合整数“左移”都是相同的。
    “右移”是不同的,对于有符合整数是“算数右移”,对于无符号整数是“逻辑右移”
    5 浮点数
    1985 IEEE standard 754
    IEEE --pronounced "Eye-Triple-Eee"
    C中不同精度的数即使数值一样比较时仍不一样。 double a = 0.2; float b = 0.2; a != b
    对于浮点数exp值的不同浮点数别别三种格式表示:
    1规格化:exp字段值的表面值不为0或全为1时。
    exp的值用e-Bias确定: e为exp字段的无符号字面值,Bias为一个常量=2^k-1 -1(32bit=127)所以 exp的值为-126~+127之间。 对于64bit浮点书exp的值为-1022~+1023.
    尾数M的值等于1+frac。 其中0<= frac <1.这种表示可以把1省略掉,所以也叫隐含的以1开头的表示。
    2.非格式化:exp字段全为0时。
    阶码E的值E=1-Bias。(Bias同上)
    尾数M的值M=frac (就是frac字段的字面值,0.frac)
    3特殊值:当exp字段全为1时。
    frac字段全为0时表示无穷,即表示有益出。
    frac字段不全为0时表示不是一个数(NaN值),又使用来表示未初始化的数据。
    IEEE浮点数的4中舍入方法
    Round-to-even (default)
    Round-toward-zero
    Round-to-down
    Round-to-up
    对于舍入一定要重视 比如
    float a = 0.3 ;
    	if (a == 0.3)
    		cout << "a == 0.3" << endl ; 
    	else
    		cout << "a != 0.3" << endl ; //输出不相等
    
    	double b = 0.3 ;
    	if (b - 0.3 < 0.000000001 || b - 0.3 > -0.000000001)
    		cout << "b == 0.3" << endl ;//输出这项
    	else
    		cout << "b != 0.3" << endl ;
    
    浮点加法不具有结合性和分配性。这是浮点数重要的群属性。
    ###在GNU 中开启支持无穷和nan的方法
    define _GNU_SOURCE 1
    include <math.h>
    
    开启后就会支持“INFINITY”,“NAN”的常量。
    2011-06-16 10:09:52 回应
  • 第188页

    Stack grown toward down
    Stack grown toward down


    注意乘法和除法的区别。
    imull/mull 提供两个32bit的值的全64bit乘法结果。imull是有符号,mull无符号。
    一个opend必须有eax隐式提供,另一个有opend显示提供。
    乘法的结果高32bit存放在edx,第32bit存放在eax。
    ####对于除法
    idivl将[%edx][%eax]作为被除数,隐士提供。除数有opend提供。
    结果:商储存在%eax中,余数在%edx中。
    cltd指令将%eax符号扩展到%edx.
    divl:无符号除法使用:会将%edx设置位0.
    ####summary
    要乘阴A, 被显乘,得高D低A。
    要除阴D带A,被显除,得商D余A
    ####Conditon instructions
    ##设置状态寄存器

    测试指令只改变状态寄存器其他的寄存器不受影响
    ##访问状态寄存器(判断大小)


    #####条件转移指令
    为超线程技术提供支持,加快指令指向,把条件控制变成数据控制

    #####技巧
    test %edx,%edx
    je Targ
    对这个是汇编的技巧,刚开始也很费解呵呵.
    TEST影响 C,O,P,Z,S 而JL根据 SF≠OF AND ZF=0跳转
    要想跳转至少ebx中的数不能为0 (为0了ZF就该为1了)
    而OF位没有溢出所以始终为0 所以只能是SF为 1 才跳转
    所以 条件满足SF=1 OF=0 ZF=0时也就是当ebx中的数为负数时才跳转.
    也就是如果ebx中的数为负跳到TARG
    ###Procedures
    参数通过stack来传递。
    stack是想下生长(向低地址)
    ##一个procedure有一个约定的格式
    #1 pushl %ebp ;把ebp如栈保存caller的ebp
    #2 movl %esp, %ebp ; 把ebp重定位到新procedure栈的开始处,即%ebp指向栈中刚才保存的%ebp
    #3 pushl %callee-save ;[可选]为procedure中用到的callee-save寄存器保存值
    #4 subl $space,%esp; [可选]为procedur的局部变量开辟stack空间,
    ...<codes>
    #返回caller的工作,
    #-4 popl callee-save ; 恢复caller-save寄存器的值
    #-3 addl $space,%esp;清位空位procedure开辟的stack空间,
    #-2 popl %ebp
    #-1 ret; 把%esp指向的地址出栈,跳转到这个出栈的地址出,即在执行ret之前需要把esb指向return的地址。
    注:一般为了执行速度,stack开辟的空间都是16的倍数。
    -3,-2步可以用leave指令代替,leave 等价于 movl %ebp,%esp
    popl %ebp
    2011-08-14 11:29:46 2回应