LOADING

加载过慢请开启缓存 浏览器默认开启

CSAPP 02-Bits-ints-part2

Addition加法

  1. 无符号数加法:\(s = UAdd_w(u,v) = (u +v)\% 2^w\);结果寄存器会截断溢出的1位;
    1. 溢出时,结果一定小于任何一个加数;
  2. 有符号数加法:\(s = (int)((unsigned)u + (unsigned)v)\)
    1. 正溢出:\(x + y \ge 2^{w-1}\),截断后结果为\(x + y - 2^w\)
    2. 负溢出:\(x + y < 2^{w-1}\),截断后结果为\(x + y + 2^w\)
    3. 正 + 负:不可能溢出;
  3. 用加法实现减法:\((A - B)_{\text{补}} = (A)_\text{补} + (-B)_\text{补}\)
    1. 如何求\((-B)_\text{补}\)
      \((B)_\text{补} + (-B)_\text{补} = 11\cdots 1\)
      \(\sim(B)_\text{补} + (B)_\text{补} + 1 = 11\cdots 1 + 1 = 0\)
      \((-B)_\text{补} = \sim (B)_\text{补} + 1\)
  4. 加法逆元:
    1. 无符号数:\(-x = 2^w - x(x \ne 0)\),0的逆元是0;
    2. 有符号数:\(x + (-x) = 0\),注意特例\(T_{min},10\cdots 0 + 10\cdots 0 = 0\),即\(-T_{min} = T_{min}\)

Adder加法器


* 当做减法(Sub = 1)或产生进位(Co = 1)时,CF = 1,表示发生借位或进位;
* SF = 运算结果的符号位;
* ZF = 1 if Sum = 0;
* OF = 1 if 两个加数同号但与Sum异号(即上述发生溢出的情形);

以上题为例:

unsigned int x = 1000 0110;
unsigned int y = 1111 0110; // -y_补 = 00001010

int m = x = 1000 0110 = -122;
int n = y = 1111 0110 = -10;

# CF = 1(减法有借位),OF = 0(并没有溢出),SF = 1;
unsigned int z1 = x - y = 1000 0110 + 00001010 = 10010000 = 144;
int k1 = m - n = 10010000 = -112 = -112 - (-10);

# CF = 1(有进位),OF = 1(发生溢出),SF = 0;
unsigned int z2 = x + y = 1000 0110 + 11110110 = 01111100 = 124 = (134 + 246) % 256;
int k2 = m + n = 01111100 = 124 = -122 - 10 + 256;

Multiplication

  1. 无符号数乘法:和加法类似进行截断;
  2. 补码乘法:先按无符号数进行乘法运算截断,然后将结果转化为有符号数;
  3. 变量与常数之间的乘运算(左移):
  4. 变量与常数之间的除运算(算术右移):
  5. 如果负数要向0取整,记得加偏移量;即:\(x = (x + 1<<k-1)>>k\)