What & How & Why

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:comp_n_arch:courses:fnti_i:week_2 [2025/04/03 14:19] – [2's Complement(补码)] codingharecs:comp_n_arch:courses:fnti_i:week_2 [2025/04/05 12:34] (当前版本) – [控制位与 16bits 输出位的真值表] codinghare
行 77: 行 77:
 ===2's Complement(补码)=== ===2's Complement(补码)===
 这种方式下,所有的负数都用 bits 可以表示数字的总数来减去负数对应的整数,即: 这种方式下,所有的负数都用 bits 可以表示数字的总数来减去负数对应的整数,即:
 +2nx2^n-x
 +比如:
 +<code CIL>
 +// 4 bits, total numbers: 2^4 = 16
 + 3 -> 0011
 +// decimal
 +-3 -> 16 - 3 = 13 -> 2^3 + 2^2 + 2^0 -> 1101
 +</code>
 +这种情况下,正数的表达范围为 [0,2n11][0, 2^{n-1} - 1],负数的表达范围为 [1,2n1][-1, -2^{n-1}]
 +==补码的优势==
 +使用补码表示负数可以将负数的加法(减法)转化为加法:
 +\\ \\ 
 +{{ :cs:comp_n_arch:courses:fnti_i:2s_complement_add_neg.jpg?250 |,}}
 +根据上面的例子,这个过程分为了三步:
 +  - 求出负数的补码结果(正数,比如 2=162=14-2 = 16 - 2 = 14
 +  - 将得到的正数转换为二级制相加
 +  - 当存在 overflow 时,溢出位将被自动丢弃,比如此处 14+13=2714+13=27,丢弃溢出位后结果为 2716=1127-16 = 11
 +  - 1111 是以补码形式,根据公式,负数的表现形式为:24positiveNumber=112^4 - positiveNumber = 11。可以得到正数的值为 55,因此 1111 对应的负数为 5-5
 +===计算 -x===
 +上面计算负数的过程是将二进制转化为十进制来进行的。实际上,利用补码公式的变形,就可以很轻松的用二进制直接计算负数:
 +$$
 +2^n-x = 1 +(2^n-1) -x
 +$$
 +观察一下上面的变形,可以发现:
 +<code CIL>
 +1 -> 1
 +2^n - 1 -> 11111....1111
 +</code>
 +那么也就是说,x-x 的实际结果,等于所有 bits 都是 11 的数减去 xx 对应的二进制,再加上一。比如 2-2,如果以 4 bits 的
 +二进制表示,就是:
 +<code CIL>
 +16 - 2
 +-> 15 - 2 + 1
 +-> 1111 - 0010 + 1
 +-> 1101 + 1
 +-> 1110
 +</code>
 +从形式上来看,xx 的负数结果实际上是直接将 xx 的二进制**按位翻转**后再**加上一**得到的。
 +====Arithmetic Logic Unit====
 +//Arithmetic Logic Unit// (ALU) 在冯诺依曼架构中充当了很重要的角色。具体的来说:
 +  * ALU 扮演的是函数的角色,也就是接受输入,然后按指定的方法计算结果的的计算单元。
 +  * ALU 对应的函数是**提前定义**的,**算术**或**逻辑**运算的一种(或是这两者的组合)
 +<WRAP center round box 100%>
 +ALU 的设计在硬件和软件中均可实现。硬件实现下,ALU 的速度会更快,但成本会更高。
 +</WRAP>
 +===实例:Hack ALU===
 +本课例子(HACK ALU):
 +  * 接收两个 16 bits 的输入
 +  * 得到一个 16 bits 的输出和两个 1 bits 的输出。
 +  * 实现了一系列的(总共18个)**基础**函数
 +  * 调用哪个函数通过结构图正上方的 6 个 1 bit 的输入来决定。
 +其结构图如下:
 +\\ \\ 
 +{{ :cs:comp_n_arch:courses:fnti_i:hack_alu.jpg?300 |}}
 +\\ 
 +==控制位与 16bits 输出位的真值表==
 +Hack ALU 常用的 18 种运算的真值表如下:
 +\\ \\ 
 +{{ :cs:comp_n_arch:courses:fnti_i:hackalu_truetable.jpg?400 |}}
 +\\ 
 +上面 6 个控制位均在 0 和 1 时代表了两种不同的运算:
 +\\ \\ 
 +{{ :cs:comp_n_arch:courses:fnti_i:contorl_bits_alu.svg?300 |}}
 +\\ \\ 
 +整个计算过程从左到右进行运算,前面的运算结果会作为下一次的算子参与新的运算。比如下面的例子:
  
-$$\textttt{2^n - x}$$+<code CIL> 
 +// input 
 +x = 0010 
 +y = 1011 
 + 
 +// calculation:- x 
 +// control bits sequence from the turth table 
 +0 0 0 1 1 1 
 + 
 +// compute process 
 + 
 +zx = 0 // do nothing 
 +x = 0010 
 +y = 1011 
 + 
 +zy = 0 // do nothing  
 +x = 0010 
 +y = 1011 
 + 
 +zy  = 0 // do nothing 
 +x = 0010 
 +y = 1011 
 + 
 +ny = 1 // y = !y 
 +x = 0010 
 +y = 0100 
 + 
 +f = 1 // out = x + y 
 +x = 0010 
 +y = 0100 
 +out = 0110 
 + 
 +no  = 1 // out  = !out 
 +out = 1001 
 +</code>