admin管理员组文章数量:1130349
《Computer Systems: A Programmer’s Perspective》第三章 Machine-Level Representation of Programs
3.1 A Historical Perspective(历史回顾)
- 早期程序直接编写机器代码,现代使用高级语言(如C)编写,编译器/汇编器将其翻译为机器指令。
- 汇编语言是机器语言的助记符(例如
movl代替机器码)。 - 指令集架构(ISA)定义了处理器支持的操作。
扩展:了解不同架构(如 x86, x86-64, ARM)之间的指令风格差异。
3.2 Program Encodings(程序编码)
3.2.1 Machine-Level Code
- 使用 x86-64 汇编语言进行解释。
- 编译器生成
.s文件(汇编),汇编器再转换成机器码(ELF目标文件)。
3.2.2 Code Examples
long fun(long x) {
return x + 1;
}
编译为:
fun:
addq $1, %rdi
movq %rdi, %rax
ret
3.2.3 Formatting
- 汇编中常见指令格式:
操作数, 目的 - 所有整数运算基于64位寄存器(如
%rax,%rdi)
3.3 Data Formats(数据格式)
- 整数、浮点数、指针等数据类型在内存中按字节存储。
- 使用两种基本数据布局:小端序(little-endian) 和 大端序(big-endian)。
3.4 Accessing Information(访存方式)
3.4.1 Operand Specifiers
- Immediate(立即数):
$0x10 - Register:
%rax - Memory:
8(%rbp),(%rax,%rbx,4)
3.4.2 Data Movement Instructions
mov(数据移动),lea(地址计算),push/pop(栈操作)
3.4.3 示例:将数组元素加倍
void scale(long *a, long n) {
for (long i = 0; i < n; i++) a[i] *= 2;
}
3.4.4 Stack Data
push:将数据入栈pop:从栈中弹出数据
3.5 Arithmetic and Logical Operations
3.5.1 lea(Load Effective Address)
- 通常用于地址计算,速度比乘法快
lea (%rdi,%rdi,2), %rax ; rax = rdi*3
3.5.2 一元与二元操作
neg,not,add,sub,imul,and,or,xor
3.5.3 位移操作
shl,shr,sar
3.5.5 特殊操作
- 整除、模:
idiv,mul
3.6 控制结构(Control Flow)
3.6.1 Condition Codes
- 标志位(Z, S, OF, CF)反映算术/逻辑结果
3.6.3 跳转指令
jmp,je,jne,jg,jle, 等
3.6.5 条件执行(if/else)
- 通过条件跳转控制执行路径
3.6.6 条件移动
cmovxx指令避免分支,提高性能(对现代CPU友好)
3.6.7 循环
for,while均转为cmp+jump+label组合
3.6.8 Switch 语句
- 使用跳转表(jump table)优化
3.7 Procedures(过程/函数调用)
3.7.1 运行时栈结构
- 函数调用过程中维护返回地址、局部变量、保存的寄存器等。
3.7.2 Control Transfer
call和ret控制跳转与返回
3.7.3 Data Transfer
- 参数传递通过寄存器
%rdi,%rsi,%rdx,%rcx,%r8,%r9
3.7.4 栈上局部变量
- 通过
subq分配栈空间,局部变量通过偏移寻址
3.7.6 递归调用
- 每次调用都独立分配栈帧,堆栈不断增长
3.8 数组
3.8.1 基本原则
- 元素访问公式:
base + index * element_size
3.8.3 多维数组
a[i][j]转换为*(a + i * cols + j)
3.8.5 可变长度数组
- 栈帧中动态分配,注意对齐和安全性
3.9 混合结构体
3.9.1 struct
- 成员按声明顺序排列,有 padding
- 访问某成员通过偏移量
3.9.2 union
- 所有成员共享一块内存
3.9.3 对齐(Alignment)
- CPU 更快读取对齐的数据;结构体可能插入 padding 增加对齐
3.10 指针与调试
3.10.1 理解指针
- 指针是变量地址的抽象;间接访问通过
*p和p->x
3.10.2 使用 GDB
- 设置断点、打印变量、反汇编指令
3.10.3 缓冲区溢出
- 超出数组边界写入会破坏栈帧、控制流
3.10.4 缓冲区溢出防护
- 栈随机化(ASLR)、栈保护符号(canary)
3.10.5 支持变长栈帧
- 如
printf需要处理不定参数
3.11 浮点代码
3.11.1 移动与转换
movss,movsd,cvtsi2ss,cvttss2si
3.11.2 浮点过程
- 与整数函数类似,浮点参数/返回值通过 SSE 寄存器传递
3.11.3 算术运算
addss,mulss,divsd等对应 float/double 运算
3.11.6 比较与分支
- 使用
ucomiss,ucomisd进行无序比较(支持 NaN)
总结(3.12)
- 本章深入分析 C 语言程序如何映射到机器级语言。
- 理解指令执行、函数调用、内存访问与布局、控制结构实现,为性能优化、安全分析、逆向工程等打下基础。
《Computer Systems: A Programmer’s Perspective》第三章 Machine-Level Representation of Programs
3.1 A Historical Perspective(历史回顾)
- 早期程序直接编写机器代码,现代使用高级语言(如C)编写,编译器/汇编器将其翻译为机器指令。
- 汇编语言是机器语言的助记符(例如
movl代替机器码)。 - 指令集架构(ISA)定义了处理器支持的操作。
扩展:了解不同架构(如 x86, x86-64, ARM)之间的指令风格差异。
3.2 Program Encodings(程序编码)
3.2.1 Machine-Level Code
- 使用 x86-64 汇编语言进行解释。
- 编译器生成
.s文件(汇编),汇编器再转换成机器码(ELF目标文件)。
3.2.2 Code Examples
long fun(long x) {
return x + 1;
}
编译为:
fun:
addq $1, %rdi
movq %rdi, %rax
ret
3.2.3 Formatting
- 汇编中常见指令格式:
操作数, 目的 - 所有整数运算基于64位寄存器(如
%rax,%rdi)
3.3 Data Formats(数据格式)
- 整数、浮点数、指针等数据类型在内存中按字节存储。
- 使用两种基本数据布局:小端序(little-endian) 和 大端序(big-endian)。
3.4 Accessing Information(访存方式)
3.4.1 Operand Specifiers
- Immediate(立即数):
$0x10 - Register:
%rax - Memory:
8(%rbp),(%rax,%rbx,4)
3.4.2 Data Movement Instructions
mov(数据移动),lea(地址计算),push/pop(栈操作)
3.4.3 示例:将数组元素加倍
void scale(long *a, long n) {
for (long i = 0; i < n; i++) a[i] *= 2;
}
3.4.4 Stack Data
push:将数据入栈pop:从栈中弹出数据
3.5 Arithmetic and Logical Operations
3.5.1 lea(Load Effective Address)
- 通常用于地址计算,速度比乘法快
lea (%rdi,%rdi,2), %rax ; rax = rdi*3
3.5.2 一元与二元操作
neg,not,add,sub,imul,and,or,xor
3.5.3 位移操作
shl,shr,sar
3.5.5 特殊操作
- 整除、模:
idiv,mul
3.6 控制结构(Control Flow)
3.6.1 Condition Codes
- 标志位(Z, S, OF, CF)反映算术/逻辑结果
3.6.3 跳转指令
jmp,je,jne,jg,jle, 等
3.6.5 条件执行(if/else)
- 通过条件跳转控制执行路径
3.6.6 条件移动
cmovxx指令避免分支,提高性能(对现代CPU友好)
3.6.7 循环
for,while均转为cmp+jump+label组合
3.6.8 Switch 语句
- 使用跳转表(jump table)优化
3.7 Procedures(过程/函数调用)
3.7.1 运行时栈结构
- 函数调用过程中维护返回地址、局部变量、保存的寄存器等。
3.7.2 Control Transfer
call和ret控制跳转与返回
3.7.3 Data Transfer
- 参数传递通过寄存器
%rdi,%rsi,%rdx,%rcx,%r8,%r9
3.7.4 栈上局部变量
- 通过
subq分配栈空间,局部变量通过偏移寻址
3.7.6 递归调用
- 每次调用都独立分配栈帧,堆栈不断增长
3.8 数组
3.8.1 基本原则
- 元素访问公式:
base + index * element_size
3.8.3 多维数组
a[i][j]转换为*(a + i * cols + j)
3.8.5 可变长度数组
- 栈帧中动态分配,注意对齐和安全性
3.9 混合结构体
3.9.1 struct
- 成员按声明顺序排列,有 padding
- 访问某成员通过偏移量
3.9.2 union
- 所有成员共享一块内存
3.9.3 对齐(Alignment)
- CPU 更快读取对齐的数据;结构体可能插入 padding 增加对齐
3.10 指针与调试
3.10.1 理解指针
- 指针是变量地址的抽象;间接访问通过
*p和p->x
3.10.2 使用 GDB
- 设置断点、打印变量、反汇编指令
3.10.3 缓冲区溢出
- 超出数组边界写入会破坏栈帧、控制流
3.10.4 缓冲区溢出防护
- 栈随机化(ASLR)、栈保护符号(canary)
3.10.5 支持变长栈帧
- 如
printf需要处理不定参数
3.11 浮点代码
3.11.1 移动与转换
movss,movsd,cvtsi2ss,cvttss2si
3.11.2 浮点过程
- 与整数函数类似,浮点参数/返回值通过 SSE 寄存器传递
3.11.3 算术运算
addss,mulss,divsd等对应 float/double 运算
3.11.6 比较与分支
- 使用
ucomiss,ucomisd进行无序比较(支持 NaN)
总结(3.12)
- 本章深入分析 C 语言程序如何映射到机器级语言。
- 理解指令执行、函数调用、内存访问与布局、控制结构实现,为性能优化、安全分析、逆向工程等打下基础。
本文标签: 第三章读书笔记ProgrammerSystemsperspective
版权声明:本文标题:【读书笔记】《Computer Systems: A Programmer’s Perspective》第三章 Machine-Level Representation of Programs 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/jiaocheng/1758687047a2782876.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论