深入理解计算机系统第三章笔记

3.2程序编码

linux->gcc -Og -o p p1.c p2.c
gcc指GCC C编译器
-Og 告诉编译器使用生成符合原始C代码整体结构的机器代码优化
-o是增加优化级别
linux->gcc -Og -S p1.c
生成p1.s文件,即为p1.c的汇编代码
linux->gcc -Og -c p1.c
生成p1.c的目标代码文件p1.o,二进制格式
他的16进制为:53 48 89 d3 e8 00 00 00 00 48 89 03 5b c3

1.C预处理器扩展源代码,插入所有用#include命令指定的文件,并扩展所有用#define声明指定的宏
2.编译器产生源文件的汇编代码p1.s,p2.s
3.汇编器将汇编代码转化为二进制目标代码(机器代码的一种,他包含所有指令的二进制表示,但还没有填入全局值的地址)文件p1.o,p2.o
4.链接器目标代码文件与实现库函数(如printf)代码合并,产生最终的可执行代码文件p(相当于会找调用的函数的地址然后通过链接器合并)

3.2.1机器级代码

1.程序计数器:%rip表示,通常存储下一条指令在内存中的地址
2.整数寄存器:包含16个命名的位置,分别存储64位的值,可以存储地址或整数数据,有的寄存器用来存储某些重要的程序状态,其他的用来保存临时数据如过程参数和局部变量及函数的返回值
3.条件码寄存器保存最近执行的算术或逻辑指令的状态信息(比如实现if和while语句)
4.一组向量寄存器可以存放一个或多个整数或浮点数

机器级代码的表示

机器级代码只是简单将内存看成一个很大的,按字节寻址的数组
C语言的聚合数据类型如数组和结构.在机器代码中用一组连续的字节表示
对标量数据类型,汇编代码不区分有符号和无符号整数,不区分各种类型的指针,甚至不区分整数和指针

程序内存

程序的可执行机器代码 操作系统需要的一些信息 用来管理过程调用和返回的运行时栈 用户分配的内存块(用malloc库函数分配的)

一条机器指令只执行基本的操作

存放在寄存器的两个数字相加
在存储器和寄存器之间传送数据
条件分支转移到新的指令地址

3.4.2数据传送指令

movb 传送字节
movw 传送字
movl 传送双字 (例外目的为寄存器时,movl会将寄存器高位4字节设置为0)
例如movl $-1,%eax 00000000FFFFFFFF
movq 传送四字
movabsq 其他只能将32位立即数传送到寄存器,而且absq能直接将64位立即数只能传送到寄存器

movabsq -1,%al %rax = 00112233445566FF
movw -1,%eax %rax = 00000000FFFFFFFF
movq $-1,%rax %rax = FFFFFFFFFFFFFFFF

剩余字节填充为0
movzbw 零扩展从字节传送到字
movzbl 零扩展从字传送到双字
bwlq排列组合,但是没有movzlq因为movl就能替代movzlq
剩余字节通过符号扩展填充
movsbw 做了符号扩展的字节传送到字
movsbl 做了符号扩展的字节传送到双字
ctlq %eax符号扩展到%rax
bwlq排列组合

你可能感兴趣的:(深入理解计算机系统第三章笔记)