CSAPP——第2章信息的表示和处理

第 2 章 信息的表示和处理

(用来记录一些一直困惑的点)

有关大端小端

书 P29 的两幅图比较形象的给出了0x01234567大端法和小端法在内存中储存的样子,小端实际上就是将最低有效字节储存在内存中低地址(靠前面)的位置。

补充一句,当阅读像此类小端法机器生成的机器级程序表示时,经常会将字节按照相反的顺序显示。书写字节序列的自然方式是最低位字节在左边,而最高位字节在右边,这正好和通常书写数字时最高有效位在左边,最低有效位在右边的方式相反。

整数表示

有关补码原码

C 语言中有符号和无符号类型比较时,会隐式地将有符号参数强制类型转换位无符号数,并假设这两个数都是非负地,来执行这个运算,这会导致一些可能难以理解的比较结果。比如-1<0U为假(因为\(T2U(-1) = UMax\)),以及2147483647 > (int) 2147483648U为真。

另外,在视频的总结中还举了一个例子,循环for(unsigned int i = n-1; i>=0 ; i--)会是无限的,因为 unsigned 总是被认为非负的(从\(0\) jump 到 \(UMax\))。同时更重要的,循环for(int i = n-1; i-sizeof(char) >= 0 ; i--也会是无限的!,结合上面隐式转换,sizeof返回的结果是 unsigned,导致循环终止判断的左表达式都会被隐式转换为 unsigned 再与\(0\)进行比较。如果我们只是看着这个程序,很难知道其崩溃的原因。

Summary Casting Signed <-> Unsigned: Basic Rules

  • Bit pattern is maintained
  • But reinterpreted
  • Can have unexprected effects: adding or subtracting \(2^w\)
  • Expression containing signed and unsigned int
    • int is cast to unsigned!!

有关位模式的直觉- -

整数部分最后再次回到,Signed 和 Unsigned 的讨论,很多时候我们需要谨慎小心的使用 unsigned,比如视频中提到的用for (size_t i = cnt - 2; i < cnt ; i--)写法习惯来避免在 loop index 中使用 unsigned 时出现问题,这样更加更加保险(因为 C 标准并没有给出溢出后情况如何,该循环的终止条件就是溢出)。size_t defined as unsigned value with length = word size.

那最后,Why Should I Use Unsigned?

  • Do Use When Performing Modular Arithmetic(Multiprecision arithmetic, Encryption)
  • Do Use When Using Bits to Represent Sets(Logical right shift, no sign extention)

Representations in memory, pointers, strings

Byte-Oriented Memory Organization

  • Programs refer to data by address
    • Conceptually, envision it as a very large array of bytes
    • An address is like an index into that array (space up to \(2^47\))
  • Note: system provides private address spaces to each "process"

字长(Word Size):通常来说,可以表示该语言中一个指针的大小(地址的空间),或是表示某机器习惯处理的 x 位数值运算(比如 32 位,64 位)。不应该太过纠结于具体定义,我们常见过可以指定源代码编译时选择 64 位的还是 32 位的,字长不是完全的硬件特性,而是由硬件和编译器共同决定的。

课程是先讲的整数表示,运算,再讲这些和大小端的(一个多字节字中字节的存储顺序)。