X

曜彤.手记

随记,关于互联网技术、产品与创业

吉 ICP 备10004938-2号

《X86/X64 体系探索及编程》读书笔记


又一本“砖头”,在 Intel 手册的基础之上讨论 X86/X64 处理器组成及相关编程方式的一本书。限于精力,有选择性地读一读吧

第一章、数与数据结构

  1. (Page:4)X86/X64 体系使用的是“小端序”,即:MSB 对应着存储器的高地址位,LSB 对应着存储器的低地址位。而在诸如 PowerPC 等 RISC 体系下的某些架构,则可能使用“大端序”。
global _main
section .data
msg: db "It's little-endian based!", 10
foo: dd 0

section .text
exit:
  mov rax, 0x02000001
  xor rdi, rdi
  syscall
_main:  ; entry here.
  mov qword[rel foo], 1
  test byte[rel foo], 1
  jnz .succeed  ; test whether it's little-endian.
  call exit
.succeed:
  mov rax, 0x02000004
  mov rdi, 1
  mov rsi, msg
  mov rdx, 13
  syscall
  call exit
  1. (Page:6)在 X86/X64 体系中,指令处理数据分为“基础(fundamental)”和“数值(numeric)”两大类。前者包括:byte(8 位)\ word(16 位)\ doubleword(32 位)\ quadword(64 位),它们代表指令能一次性处理的数据宽度。后者主要使用在运算类指令上,包括:
  1. (Page:7)不存在 unsigned 浮点数(IEEE-754 有小数位)。
  2. (Page:7)在 X86 中,对整数的加减法运算(乘除会在具体指令上进行区分)不会识别 signed 与 unsigned 的区别。而是会同时根据两种情况下的运算结果来修改 eflags 的标志位(比如 OF 与 SF),具体如何解释则由上层程序负责。而 RISC 体系普遍会在指令层上进行假定运算(比如 add 与 addu,一个针对 signed,另一个针对 unsigned)。
  3. (Page:9)在单精度与双精度浮点数中,“尾数”部分有一个隐式的整数位,该位的值为固定的 “1”。在扩展双精度浮点数中,“尾数”有 64 位,“指数”有 15 位;且其中隐式的整数位是显式的,在 “normal(规格化)” 数中,这个位必须为 1,否则属于 “denormal(非规格化)” 数。
  1. (Page:10)“移码(biased notation)”用来解决浮点数使用 integer 方法进行比较时出现的问题,通过使用 unsigned 值来简化指数的比较过程
  1. (Page:11)在 NASM 中使用浮点数字面量值,分别对应不同的编码方式(__float32__ / __float64__ / __float80e__):
global _main
section .text
exit:
  mov rax, 0x02000001
  xor rdi, rdi
  syscall
_main:  ; entry here.
  mov rax, __float32__(0.5)
  call exit
  1. (Page:11)IEEE-754 其他实数编码格式:

  1. (Page:17)IEEE-754 的四种舍入模式(用于在编码类型转换时舍入尾数部分):
  1. (Page:17)FPU(Float Point Unit):浮点运算单元。在大多数现代通用计算机架构中,一个或多个浮点运算单元会被集成在 CPU 中。浮点数的计算也会采用独立的寄存器,比如 XMM 寄存器。
  2. (Page:17)浮点数中的溢出分为两种:

  1. (Page:20)在 BCD 码中,一个十进制数的每一位,使用 8 位的二进制进行编码,如 15 的 BCD 编码为 “15H”。而在 “packed BCD” 中,每个 BCD 数字使用 4 位来表示。X86 下可以使用 aaa 指令来将累加器(AX)中的值转换为非压缩的 BCD 码。

第二章、X86/X64 编程基础

  1. (Page:24)C 语言不能直接转换为机器语言,要先由 C 编译器编译出汇编代码,然后再由汇编器生成机器指令,最终再由链接器将这些变量的地址定下来(符号重定向)。

  1. (Page:24)X86 机器是 CISC 体系,指令的长度不是固定的。其中最短的指令 1 字节,最长的指令 15 字节。
  2. (Page:26)C 语言中的 __stdcall 与 __cdecl 调用规范会使用栈来传递参数,而使用寄存器来传递参数能获得更高的效率。

(待更新)



这是文章底线,下面是评论
  暂无评论,欢迎勾搭 :)