汇编语言程序设计笔记
The microprocessor and its architecture (Chap. 1-2)
- 32位和64位架构的计算资源对比

运算资源:寄存器

| 名称 | 作用 | 备注 |
| RAX(64bit) | 累加寄存器 | 有单独的ADD代码,代码密度更高 |
| RBX(64bit) | 基址寄存器 | 无特殊功能 |
| RCX(64bit) | 计数寄存器 | 用于loop等需要计数的指令中 |
| RDX(64bit) | 数据寄存器 | 乘除法指令中使用 |
| RBP(64bit) | 基指针寄存器 | 指向当前栈帧的基地址 |
| RSI(64bit) | 源变址寄存器 | 字符串操作指令中使用 |
| RDI(64bit) | 目的变址寄存器 | 字符串操作指令中使用 |
| R8 - R15 | 扩展寄存器 | 64bit架构下新增的8个通用寄存器 |
| 数量 | bits | 内容 |
| 16 | 8-bit low-byte registers | AL, BL, CL, DL, SIL, DIL, BPL, SPL, R8B-R15B |
| 4 | 8-bit high-byte registers | AH, BH, CH, DH, addressable only when no REX prefix is used |
| 16 | 16-bit registers | AX, BX, CX, DX, DI, SI, BP, SP, R8W-R15W |
| 16 | 32-bit registers | EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, R8D-R15D |
| 16 | 64-bit registers | RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8-R15 |
注意
x86架构下,只有64bit mode支持8bit的BP,SP,SI,DI寄存器(即BPL,SPL,SIL,DIL),而在32位下,它们是不开放的,最小就到16bits。
嵌套寄存器的影响规则
- 只有修改32位的寄存器会将高32位清零,修改16位或8位寄存器不会影响高位
MOV RAX, 1111111111111111H ; RAX = 1111111111111111H
MOV EAX, 22222222H ; RAX = 0000000022222222H
MOV AX, 3333H ; RAX = 0000000022223333H
MOV AL, 44H ; RAX = 0000000022223344H- 这实际上会造成并行性上的问题
并行

特殊用途的寄存器
| 名称 | 作用 | 备注 |
| RIP | 指令指针寄存器 | 指向下一条将要执行的指令地址 |
| RFLAGS | 标志寄存器 | 存储算术运算结果的状态标志位,以及控制位 |
| RSP | 栈指针寄存器 | 指向当前栈顶地址 |

status flags
| 名称 | 作用 |
| C (bit 0): | Carry flag holds the carry after addition or borrow after subtraction. |
| Z (bit 6): | Zero flag shows that the result of an arithmetic or logic operation is zero. |
| S (bit 7): | Sign flag holds the arithmetic sign of the result after an arithmetic or logic instruction executes. |
| O (bit 11): | Overflow flag occurs when signed numbers are added or subtracted. An overflow indicates the result has exceeded the capacity of the machine. |
| P (bit 2) 校验位 | Parity flag is set if the least-significant byte of the result contains an even number of 1 bits; cleared otherwise, 用于串行通讯. |
| A (bit 4) 辅助进位标志 | Auxiliary carry holds the carry (half-carry) after addition or the borrow after BCD operations between bit positions 3 and 4 of the result. |
DF flags
| 名称 | 作用 |
| D | selects increment or decrement mode for the DI and/or SI registers. |
system flags (控制作用)
| 名称 | 作用 |
| T | enables trapping through an on-chip debugging feature |
| ID | allows the use of the CPUID instruction to identify processor features |
Segment registers
| 名称 | 作用 |
| CS (code) | code segment selector |
| DS (data) | data segment selector |
| SS (stack) | stack segment selector |
| ES (extra) | extra segment selector |
| FS (general purpose) | general purpose segment selector |
| GS (general purpose) | general purpose segment selector |
注意
在64位中,不实用segment管理,但是为了兼容,仍然保留了段寄存器,但是DS,ES等都为0;CS保留了部分功能,FS,GS在基地址中仍然有用。
System registers
- 用于控制处理器,偏底层
- Debug registers:用于调试,用于硬件断点,不用于内存中运行的程序,而是直接跑在硬件上的程序
- MSR(Model Specific Registers):跟特定的CPU型号相关,用于控制CPU的某些特性
不同运行模式与寄存器

Long Mode
- 兼容模式,可以运行32和16位的程序
- 64位模式,可以运行64位的程序
- Legacy Mode
- System Management Mode:用于处理系统管理中断,如电源管理,温度监控等
启动过程:
- 启动进入实模式
进入保护模式
- 进入虚拟模式,运行实模式代码
- 回到实模式
进入长模式(兼容模式),此时 必须要启用分页机制
- 进入64位模式
运算资源:内存
基本要求
- 重定位 (Relocation):相对位置和绝对位置,代码编写的地址和实际运行的地址可能不同,使用segment/paging机制
- 保护:防止非法访问
- 共享:多个程序可以共享同一段内存
实模式
- code segment register defines the start of the code segment
- The instruction pointer locates the next instruction within the code segment
- 物理地址 = (段寄存器值 << 4) + 偏移地址
- 早期的DOS系统中,不同的segment可能会重叠
保护模式
- Allows access to data and programs located within & above the first 1M byte of memory.
- Protected mode is where Windows operates.
- In place of a segment address, the segment register contains a selector that selects a descriptor from a descriptor table. The descriptor describes the memory segment’s location, length, and access rights.

描述符 (descriptors)
- 记录信息:segment的location/size/privilege level
- 有多少种segments,就有多少种描述符
- 一种特殊的描述符gate,用于存储中断处理程序的入口地址
- The global/system-descriptor table (GDT) holds descriptors available to all programs (required)
- The first entry in the global descriptor table (GDT) is called the null descriptor, which must contain all zeros and may not be used for accessing memory.
- Null descriptor is used to invalidate unused segment registers. By initializing unused segment registers with null selectors software can trap references to unused segments. In 64-bit mode, it can also detect whether a program is nested (SS pointing to null descriptor).
- The local/application-descriptor table (LDT) holds descriptors used by a single program (optional)
- The interrupt-descriptor table holds only gate descriptors (required)
描述符的结构:

- Base address:描述段的起始地址
- limit:描述该段最后一个有效字节的地址
根据G位的不同,有不同的含义:
- G=0: limit表示字节数,最大为1MB
- G=1: limit表示4KB块数,最大为4GB
- 早期80286是16bits空间,32bits足以描述Base和limit
- 80386-P4:16位不足以描述32bits的空间,需要将其扩展
描述符的G位 (期末必考题)
The G or granularity bit determines the scaling of the segment limit field.
- When G = 0: segment size = (limit+1) bytes. The limit ranges from 0 to 0FFFFFH ( - 1 or 1 MB - 1).
- When G = 1: segment size = (limit+1) x 4K bytes. The limit ranges from 0FFFH ( - 1 or 4 KB - 1) to 0FFFFFFFFH ( - 1 or 4 GB - 1). 4K刚好是12位,加上原来的20位,正好32位。
Problem 1
For a descriptor with a base address of 10000000H, a limit of 001FFH, and G=0, what is the starting and ending locations?
- starting location: 10000000H
- ending location: 10000000H + 001FFH = 100001FFH
Problem 2
For a descriptor with a base address of 10000000H, a limit of 001FFH, and G=1, what is the starting and ending locations?
- starting location: 10000000H
- segment size = (limit+1) x 4K bytes = (001FFH + 1) x 4096 bytes = 00200H x 1000H = 00200000H
- ending location: 10000000H + 001FFFFFH = 101FFFFFH
权限位:

- S/Type field: The S and Type fields together specify the descriptor type and its access characteristics
- Descriptor Privilege-Level (DPL) Field: The DPL field indicates the descriptor-privilege level of the segment, with 0 specifying the most privilege and 3 the least privilege.
- A bit:是否被访问过
选择子(selector):

- 选择子一共16位,描述符index占用13bits,对应8K个描述符
权限的管理:

- 描述符的权限:描述多高级的代码可以访问对应的段(访问客体)
- 选择子的权限:描述发出访问请求的代码的权限(访问主体)
- CS寄存器的权限:CPL段记录当前CPU的权限,也相当于当前代码的权限(访问主体)
- 比较权限时,总是在两个访问主体中取权限最低(值最大)的一个与客体比较
访问数据段和访问栈
- 访问数据段:需要主体权限高于或等于客体权限

- 访问栈:为了保护私有数据,需要两个主体权限都等于客体权限

描述符表的位置
- 全局描述符表(GDT)和中断描述符表(IDT)的位置由专用寄存器GDTR和IDTR保存
- x86有专门的指令来加载和存储这些寄存器的值
由于程序需要不断地进行切换,需要有不同的描述符表,因此需要有一个任务状态段(TSS)来保存当前任务的状态
- 包括寄存器值、堆栈指针、描述符表指针等(LDTR and TR: refer to special system descriptors in the GDT. LDTR保存的并不是基地址,而是对应table的段基地址在GDT中的索引)
保护模式下内存访问的过程

如何寻找局部描述符(DS的TI位为1时):
- 使用GDTR找到GDT
- LDTR作为索引在GDT找到LDT的位置
- DS中的selector作为索引在LDT找到DS的描述符
LDTR的更新机制:
- 任务切换时,LDTR会更新,因此一个重要的方法就是将其存到任务的上下文中
- LDT是跟任务绑定的
内存模式:
- The multi-segmented model divides memory into different segments: code, data, and stack. Each segment can be accessed independently.
- The flat-memory model refers to a linear addressing paradigm. Code, data, and stacks are all contained in a single contiguous address space such that the CPU can directly address all of the available memory locations.

分页机制
- 程序看到的是逻辑地址
- 逻辑地址(使用segment)变成线性地址
- 如果使用了分页,那么它就是一个虚拟地址,需要再次转换成物理地址

地址
- 有效地址(Effective Address, EA):由指令中的偏移量和寄存器计算得到的地址
- 逻辑地址(Logical Address):由段寄存器和有效地址组成的地址
- 线性地址(Linear Address):经过段转换后的地址
- 物理地址(Physical Address):实际存在的内存地址

page
- 页的大小:long mode:4KB/2MB/1GB, Legacy mode:4KB/2MB/4MB
- 多层映射:Page translation uses a hierarchical data structure called a page-translation table to translate virtual pages into physical-pages. The number of levels range from 1 to 4.

多级分页
下面的讨论摘自OS笔记:
我们将使用以下的参数进行讨论:
- address space size: bytes
- page size
- entry size
- page table size
首先,我们使用如下的Paging配置:
| virtual address space size | 64 bits |
| entry size | 4 Bytes |
| page size | 4 KB |
| Physical memory | 4 GB |
- 如此一来,64bit的空间一共有个page需要映射
- 每个entry size为4 Bytes,因此需要大小为的Page table
- 考虑到Page table必须是一个连续的空间,而且不同的process都拥有各自的page table, page table占用的空间将极其可观!
接着使用以上的配置考虑一个极端情况:
- 一个进程只被分配了两个page,逻辑地址分别为0x00000000和0xffffffff,那么它的page table只有两个有效的entry,其他的4MB-8B的空间都被浪费了!
使用Page存储Page table:
- 之前讲到了,不合理的Page Table会极大浪费内存空间,如果使用Page来存储Page table,就可以避免这种浪费吗?
- 使用大小为4KB的Page,一个Page可以存储个entry,因此Page table的大小为 个Page
- 实际上,只有第一个和最后一个两个Page被使用,剩余的1022个Page都是因为需要维护Page table的连续性而用于充数空闲Page!
Hierarchical Paging:
- 基本思想:将Page table做多层映射,以两层为例,第一层Page table存储第二层Page table的帧号;第二层Page table存储逻辑地址对应的帧号
- 优点:省内存,需要Page的时候才会申请
- 缺点:这次又要多访存一次了,使用不同大小的TLB能够减少访存次数
在有大量无效PTE的情况下,Hierarchical Paging能够节省大量内存空间。

经典题目
Problem: Consider a system using multi-level paging scheme. The page size is 4 KB. The physical memory is 16 TB ( bytes) and virtual address is 32 bits long. The page table entry size is 4 bytes.
Find:
- How many levels of page table will be required?
- Give the divided physical address and virtual address.
Solution:
- 16TB的空间有个page
- 一个Page含有个entry
- 因此需要10bits作为索引
- page offset为12bits
- 32-12=20bits,因此需要20/10=2层page table
- 每一个页表都是4KB对齐,说明后12位都是0,只需要32位就可以找到页表对应的物理地址

页表项

Bit 0: P (Present) - Present Bit
- P = 1: Valid. The PDE contains a valid physical address.
- P = 0: Invalid. A Page Fault exception (#PF) is triggered.
- This is the foundation for “demand paging” and “page swapping”.
Bit 1: R/W (Read/Write)
- R/W = 1: Readable and Writable
- R/W = 0: Read-Only, any write attempt triggers Page Fault
- Protects Code and Read-Only Data, enables Copy-on-Write (CoW)
Bit 2: U/S (User/Supervisor)
- U/S = 0: Supervisor Mode (rings 0, 1, 2)
- U/S = 1: User Mode (ring 3)
- Key to implementing the isolation between kernel space and user space
多级页表中的权限保护: PDE (Page-Directory Entry), PTE (Page-Table Entry)
相关寄存器
- Paging registers
- The paging unit is controlled by the contents of the microprocessor’s control registers. Beginning with Pentium, an additional control register labeled CR4 controls extensions to the basic architecture.

- 其中当缺页异常发生时,发生异常的线性地址会被存储在CR2中
缺页异常
- A #PF exception can occur during a memory access in any of the following situations:
- A page-translation-table entry or physical page involved in translating the memory access is not present in physical memory (present/absent).
- The memory access fails the paging-protection checks (user/supervisor, read/write, or both).
- If a second page fault occurs while an earlier page fault is being delivered, the faulting linear address of the second fault will overwrite the contents of CR2.
分页模型
- 10-10-12 model (two-level paging)

- 2-9-9-12 model (three-level paging)
分页模型的扩展
- Page Size Extensions (PSE) to map linear address to physical address in 4-MBytes pages

- Physical Address Extensions (PAE) to address physical address space greater than 4 Gbytes (2-9-9-12 model)
,

由于需要支持36bit的物理地址,page number达到了36-12=24bits,于是entry的大小扩展到了8bytes。

PAE模式下的PSE (2MB):

优先级:PAE打开,自动启用PSE
TLB
- TLB和CPU cache的区别
