1. 寄存器:CPU的高速工作台
寄存器是CPU内部最核心的存储单元,就像厨师手边的调料台——容量不大但触手可及。现代CPU中,寄存器访问延迟通常在1个时钟周期内,而L1缓存需要3-4周期,主内存则高达200+周期。这种速度差异决定了寄存器在程序性能中的关键地位。
1.1 通用寄存器进化史
从8位到64位架构,寄存器家族不断扩展:
assembly复制; 寄存器位宽演变示例
mov al, 0x12 ; 8位 (8086)
mov ax, 0x1234 ; 16位 (80286)
mov eax, 0x12345678 ; 32位 (80386)
mov rax, 0x123456789abcdef0 ; 64位 (x86-64)
x64架构新增了R8-R15寄存器,配合System V调用约定,前6个参数可通过寄存器传递(rdi, rsi, rdx, rcx, r8, r9),大幅减少函数调用的内存访问。
实践技巧:在性能敏感代码中,优先使用caller-saved寄存器(如rax, rcx, rdx)可以减少保存/恢复寄存器的开销。
1.2 标志寄存器:CPU的状态指示灯
EFLAGS寄存器就像汽车仪表盘,实时反映CPU运行状态:
assembly复制cmp eax, ebx ; 设置ZF/SF/OF等标志
jg label ; 有符号大于跳转(SF=OF且ZF=0)
调试时常用的小技巧:
assembly复制pushf ; 保存当前标志位
pop ax ; 将标志寄存器值取出检查
test ax, 0x0040 ; 检测ZF位(第6位)
1.3 控制寄存器:CPU的开关面板
CR0-CR4控制着处理器的核心功能:
assembly复制; 开启分页机制示例
mov eax, cr0
or eax, 0x80000000 ; 设置PG位
mov cr0, eax
CR3寄存器存储页表基址,在进程切换时需要更新:
c复制// Linux内核中的实现示例
void switch_mm(struct mm_struct *mm) {
load_cr3(mm->pgd);
}
2. 汇编指令:CPU的语言
2.1 数据传送的艺术
MOV指令看似简单,实则暗藏玄机:
assembly复制mov eax, [ebx+esi*4+8] ; 复杂寻址模式
movsx eax, bl ; 带符号扩展
movzx ecx, al ; 零扩展
栈操作注意事项:
assembly复制push eax ; 等价于:
sub esp, 4 ; 1. ESP减4
mov [esp], eax ; 2. 存储数据
pop ebx ; 等价于:
mov ebx, [esp] ; 1. 读取数据
add esp, 4 ; 2. ESP加4
常见错误:在32位系统误用16位push/pop会导致栈不对齐,引发性能下降或异常。
2.2 算术运算的陷阱
有符号与无符号运算使用相同的指令,但解释不同:
assembly复制mov al, 0xFF
add al, 1 ; 无符号:255+1=0 (CF=1)
; 有符号:-1+1=0 (OF=0)
除法指令的特殊要求:
assembly复制; 8位除法:被除数在AX,结果AL=商,AH=余数
mov ax, 100
mov bl, 3
div bl ; AL=33, AH=1
; 32位除法:被除数在EDX:EAX
mov eax, 100
mov edx, 0 ; 必须清零EDX
mov ebx, 3
div ebx ; EAX=33, EDX=1
2.3 控制流实现原理
条件跳转依赖标志位组合:
assembly复制cmp eax, ebx
ja label ; 无符号大于跳转(CF=0且ZF=0)
jg label ; 有符号大于跳转(SF=OF且ZF=0)
循环的三种实现方式:
assembly复制; 方式1:LOOP指令(较慢)
mov ecx, 10
loop_start:
; 循环体
loop loop_start
; 方式2:DEC+JNZ(更快)
mov ecx, 10
loop_start:
; 循环体
dec ecx
jnz loop_start
; 方式3:反向计数(最佳)
xor ecx, ecx ; ecx=0
loop_start:
; 循环体
inc ecx
cmp ecx, 10
jb loop_start
3. 系统级编程实战
3.1 中断处理机制
x86中断向量表示例:
assembly复制; 设置0x80中断处理程序
cli ; 关中断
mov eax, int_handler
mov [idt+0x80*8], ax ; 偏移低16位
mov word [idt+0x80*8+2], 0x08 ; 代码段选择子
mov word [idt+0x80*8+4], 0x8E00 ; 类型=中断门
shr eax, 16
mov [idt+0x80*8+6], ax ; 偏移高16位
sti ; 开中断
int_handler:
pusha ; 保存所有通用寄存器
; 中断处理代码
popa ; 恢复寄存器
iret ; 中断返回
3.2 现代CPU特性应用
SSE指令加速图像处理:
c复制// 使用SSE实现RGBA像素Alpha混合
void alpha_blend_sse(uint8_t* dst, const uint8_t* src, size_t len) {
const __m128i alpha_mask = _mm_set1_epi32(0xFF000000);
for (size_t i = 0; i < len; i += 16) {
__m128i src_px = _mm_load_si128((__m128i*)(src + i));
__m128i dst_px = _mm_load_si128((__m128i*)(dst + i));
__m128i alpha = _mm_and_si128(src_px, alpha_mask);
// ... 混合计算 ...
_mm_store_si128((__m128i*)(dst + i), result);
}
}
4. 跨平台差异与优化
4.1 Windows与Linux调用约定对比
| 特性 | Windows x64 | System V x64 |
|------------|---
