# 程序的机器级表示
---

> ## 精通细节是理解更深和更基本概念的先决条件 "This is a subject where mastering the details is a prerequisite to understanding the deeper and more fundamental concepts"
### 机器级编程的2种抽象:指令集结构,虚拟地址
### 使用反汇编器,64位系统下指定-m32生成32位的,和书中给出的代码不一样,所以阅读本章的目的是读懂汇编代码
```
Disassembly of section .text:
0000000000000000 <sum>:
0: 8d 04 37 lea (%rdi,%rsi,1),%eax
3: 01 05 00 00 00 00 add %eax,0x0(%rip) # 9 <sum+0x9>
9: c3 retq
```
指定-m32:
```
00000000 <sum>:
0: 8b 44 24 08 mov 0x8(%esp),%eax
4: 03 44 24 04 add 0x4(%esp),%eax
8: 01 05 00 00 00 00 add %eax,0x0
e: c3 ret
```
### IA32整数寄存器

### 数据传送示例-P116
[exchange.c](exchange.c)
```
vonzhou@ubuntu:~/Github/CSAPP/chapter03$ gcc -m32 -O1 -c exchange.c
vonzhou@ubuntu:~/Github/CSAPP/chapter03$ objdump -d exchange.o
exchange.o: file format elf32-i386
Disassembly of section .text:
00000000 <exchange>:
0: 8b 54 24 04 mov 0x4(%esp),%edx
4: 8b 02 mov (%edx),%eax
6: 8b 4c 24 08 mov 0x8(%esp),%ecx
a: 89 0a mov %ecx,(%edx)
c: c3 ret
```
理解:过程加载后,xp和y分别存储在相对于寄存器esp偏移4,8的地方,这里是esp(**和书中不同**),说明了两个参数是存储在栈中,栈也是存储的一部分,只不过通过esp来控制访问的。mov 0x4(%esp),%edx 将xp的值加载到edx中,mov (%edx),%eax 将xp对应的地址处的值加载到eax中,mov 0x8(%esp),%ecx将y的值加载到ecx中,mov %ecx,(%edx)将y的值存储到xp对应的存储地址处,ret返回,返回值在eax中,正是*xp之前的值;
1. C语言中的指针其实就是地址,引用指针就是将指针取到寄存器中,然后在存储器访问中使用这个寄存器
2. 函数体中的局部变量x存在寄存器,而非存储器中
### 整数算术操作指令

LEA没用引用存储器,只是进行地址计算,而MOV是加载那个地址处的值到寄存器中。具体形式为 LEA Imm(ra,rb,n) D :表示 n * rb + ra 的值写入寄存器D
### 移位指令中,移位量是单字节编码,移位量是立即数或者放在单字节寄存器%cl中,注意只能是这个寄存器
### 一个算术操作函数产生的汇编代码分析
[arith.c](arith.c)
```c
int arith(int x, int y, int z){
int t1 = x + y;
int t2 = z * 48;
int t3 = t1 & 0xFFFF;
int t4 = t2 * t3;
return t4;
}
```
```bash
vonzhou@ubuntu:~/Github/CSAPP/chapter03$ objdump -d arith.o
arith.o: file format elf32-i386
Disassembly of section .text:
00000000 <arith>:
0: 8b 44 24 0c mov 0xc(%esp),%eax
4: 8d 04 40 lea (%eax,%eax,2),%eax
7: c1 e0 04 shl $0x4,%eax
a: 8b 54 24 08 mov 0x8(%esp),%edx
e: 03 54 24 04 add 0x4(%esp),%edx
12: 0f b7 d2 movzwl %dx,%edx
15: 0f af c2 imul %edx,%eax
18: c3 ret
```
分析:可以看到参数 x,y,z 分别放在栈的临近位置,先计算的是z * 48 而不是按函数中给出的顺序,前3条指令意思是 z -> eax -> 2 * z + z = 3z -> 3z << 4 -> 3z * 16 = 48z; 接下来的2条计算x+y;然后利用MOVZ只保留低2B;最后相乘,并且结果保存在EAX中,返回
### 机器代码提供两种低级机制来实现有条件的行为:测试数据值,然后根据测试的结果改变控制流或数据流
### 常用的条件码

### 对于不同的操作会设置/检查不同的条件码组合,下面是a,b是否相等的决策过程
SET指令的通用规则是:执行cmp指令,根据计算t=a-b设置条件码
1. 如果是补码表示形式。零标志决定了是否相等,如果不等,看OF是否发生了溢出,如果没发生溢出的话,看符号位是正(a>b)是负(a<b); 如果发生溢出,则规则对应地
2. 如果是无符号表示。看零标志和进位标志
### 在汇编代码中跳转目标用符号标号书写,汇编器及后面的链接器,会产生跳转目标的适当编码:相对(PC-relative)或绝对地址。
### 当执行PC-relative寻址时,程序计数器的值是跳转指令后面那条指令的地址,而不是跳转指令本身的地址,因为处理器将更新PC作为执行一条指令的first step
### 条件语句的编译
[absdiff.c](absdiff.c), [gotodiff.c](gotodiff.c)
```bash
absdiff.o: file format elf32-i386
Disassembly of section .text:
00000000 <absdiff>:
0: 53 push %ebx
1: 8b 4c 24 08 mov 0x8(%esp),%ecx
5: 8b 54 24 0c mov 0xc(%esp),%edx
9: 89 d3 mov %edx,%ebx
b: 29 cb sub %ecx,%ebx
d: 89 c8 mov %ecx,%eax
f: 29 d0 sub %edx,%eax
11: 39 d1 cmp %edx,%ecx
13: 0f 4c c3 cmovl %ebx,%eax
16: 5b pop %ebx
17: c3 ret
```
**cmovl**:利用前面比较得到的条件码,进行有条件的mov,这里的条件是”less than“,后面有详述
### 初探do-while的汇编代码
[fact_do.c](fact_do.c)
```bash
00000000 <fact_do>:
0: 8b 54 24 04 mov 0x4(%esp),%edx
4: b8 01 00 00 00 mov $0x1,%eax
9: 0f af c2 imul %edx,%eax
c: 83 ea 01 sub $0x1,%edx
f: 83 fa 01 cmp $0x1,%edx
12: 7f f5 jg 9 <fact_do+0x9>
14: f3 c3 repz ret
```
**可以看到:**循环控制变量n在edx中,result在eax中,跳转使用的相对地址,至于repz ret的含义不太理解,说AMD的分支预测有问题如果只用一个ret
### 初探while的汇编代码
[fact_while.c](fact_while.c)
```
00000000 <fact_while>:
0: 8b 54 24 04 mov 0x4(%esp),%edx
4: 83 fa 01 cmp $0x1,%edx
7: 7e 12 jle 1b <fact_while+0x1b>
9: b8 01 00 00 00 mov $0x1,%eax
e: 0f af c2 imul %edx,%eax
11: 83 ea 01 sub $0x1,%edx
14: 83 fa 01 cmp $0x1,%edx
17: 75 f5 jne e <fact_while+0xe>
19: f3 c3 repz ret
1b: b8 01 00 00 00 mov $0x1,%eax
20: c3 ret
```
**可以看到:**先判断条件,然后和do-while一样,在每个条件跳转指令之后都加上了repz ret
### 初探for-loop的汇编代码
[fact_for.c](fact_for.c)
```
00000000 <fact_for>:
0: 8b 4c 24 04 mov 0x4(%esp),%ecx
4: 83 f9 01 cmp $0x1,%ecx
7: 7e 16 jle 1f <fact_for+0x1f>
9: b8 01 00 00 00 mov $0x1,%eax
e: ba 02 00 00 00 mov $0x2,%edx
13: 0f af c2 imul %edx,%eax
16: 83 c2 01 add $0x1,%edx
19: 39 d1 cmp %edx,%ecx
1b: 7d f6 jge 13 <fact_for+0x13>
1d: f3 c3 repz ret
1f: b8 01 00 00 00 mov $0x1,%eax
24: c3 ret
```
可以看到没啥区别,除了控制变量递增,上述三种循环控制效率是一样的
### 基于条件传送指令的代码比基于条件控制转移的代码性能好,控制流不依赖于数据,使得处理器更容易保持流水线是满的
[absdiff_condition.c](absdiff_condition.c), [cmovdiff.c](cmovdiff.c)
```
00000000 <absdiff>:
0: 53 push %ebx
1: 8b 4c 24 08 mov 0x8(%esp),%ecx
5: 8b 54 24 0c mov 0xc(%esp),%edx
9: 89 cb mov %ecx,%ebx
b: 29 d3
没有合适的资源?快使用搜索试试~ 我知道了~
深入理解计算机系统第二版中文学习笔记与代码实践-计算机系统原理-信息表示处理-程序机器级表示-处理器体系结构-程序性能优化-存储...

共512个文件
c:352个
txt:37个
jpg:24个

需积分: 5 0 下载量 79 浏览量
2025-07-22
00:28:42
上传
评论
收藏 24.51MB ZIP 举报
温馨提示
softcnkiller深入理解计算机系统第二版中文学习笔记与代码实践_计算机系统原理_信息表示处理_程序机器级表示_处理器体系结构_程序性能优化_存储器层次结构_链接机制_异常控制流_虚拟内存_系统级I.zip深入理解计算机系统第二版中文学习笔记与代码实践_计算机系统原理_信息表示处理_程序机器级表示_处理器体系结构_程序性能优化_存储器层次结构_链接机制_异常控制流_虚拟内存_系统级I.zip
资源推荐
资源详情
资源评论




























收起资源包目录





































































































共 512 条
- 1
- 2
- 3
- 4
- 5
- 6
资源评论


普通网友
- 粉丝: 801
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 有线电视网络维护及管理分析.docx
- 20XX年清华IT软件开发实习报告.doc
- 最新计算机专业面试时自我介绍-计算机就业面试自我介绍(四篇).docx
- 无界投融汽车电子商务移动项目融资计划书.ppt
- 物联网发展资金可行性研究分析报告.doc
- 新疆2017年银行招聘考试计算机学:计算机基础试题.docx
- 市场营销网络技术契约书.docx
- 客源分析Excel表格.xlsx
- 汽车电子商务综述.ppt
- 工业互联网现场实时化实施方案.docx
- 软件工程毕业论文参考文献范文.doc
- 高校网络党校系统—考试模块.doc
- 农资连x锁经营服务网络项目可行性建议书.doc
- 《网络道德与法律》课件-.ppt
- 【基于Proteus软件电力电子课程项目驱动教学法研究】什么是任务驱动教学法.doc
- 2020年工程建设中路桥项目管理的作用论文.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
