CSAPP读书笔记-chap3-程序的机器级表示

这篇博客详细介绍了程序从高级语言到机器代码的转化过程,特别是汇编代码如何与机器的指令集架构相互作用。内容涵盖了程序编码、数据格式、访问信息、算术和逻辑操作、控制流程、过程调用和栈帧结构,以及浮点数编码等核心概念。学习汇编语言有助于理解底层原理,如处理器状态、指令格式和存储器管理,同时也涉及到程序优化、条件码、跳转指令和缓冲区溢出等安全问题。此外,文章还讨论了调试工具GDB在机器级代码调试中的应用。
摘要由CSDN通过智能技术生成

高级语言通过编译变成汇编语言,汇编代码则与特定的机器密切相关。汇编代码中包含了管理存储器(memory)和执行计算的低级指令的一些细节。编译器基于编程语言的原则、目标机器的指令集和操作系统遵循的规则,经过一系列的阶段产生机器代码。

学习汇编有助于调优;有助于理解底层原理,而不仅仅是封装调用;有助于理解黑客、安全问题

编译器还存在一定的优化操作:可能调整指令顺序、移除非必要计算、替换慢指令,甚至会将递归优化为迭代

程序编码

从源代码到机器可执行代码会经过以下几个过程:预处理-> 编译器-> 汇编器 -> 链接器

举例

gcc -Og -o p p1.c p2.c

编译包含以下几步

First, the C preprocessor expands the source code to include any files specified with #include commands and to expand any macros, specified with #define declarations.

Second, the compiler generates assembly code versions of the two source files having names p1.s and p2.s.

Next, the assembler converts the assembly code into binary object-code files p1.o and p2.o. Object code is one form of machine code—it contains binary representations of all of the instructions, but the addresses of global values are not yet filled in.

Finally, the linker merges these two object-code files along with code implementing library functions (e.g., printf) and generates the final executable code file p (as specified by the command-line directive -o p). Executable code is the second form of machine code we will consider—it is the exact form of code that is executed by the processor.

机器级代码

对于机器级代码来说,有两种抽象非常重要。第一种是机器级程序的格式和行为,定义为指令集体系结构(Instruction set architecture, ISA),它定义了处理器状态、指令的格式,以及每条指令对状态的影响。第二种抽象是,机器级程序使用的存储器地址是虚拟地址,提供的存储器模型看上去是一个非常大的字节数组。

汇编代码和原始的C代码相差比较大,一些通常对C语言程序员隐蔽的处理器状态是可见的:

  • 程序计数器(PC,用 %rip 表示)指示将要执行的下一条指令在存储器中的地址。
  • 整数寄存器文件包含 16 个命名的位置,分别存储 64 位的值。这些寄存器可以存储地址(对应于 C 语言的指针)或整数数据。有的寄存器被用来记录某些重要的程序状态,而其他的寄存器则用来保存临时数据。
  • 条件码(codition code)寄存器保存着最近执行的算术或逻辑指令的状态信息。它们用来实现控制或数据流中的条件变化。
  • 一组向量寄存器(vector registers)存放浮点数据或者多个整型数据。

C语言中的聚合数据类型,例如数组和结构,在汇编中是用连续的字节表示的。汇编代码不区分有符号或无符号整数,不区分各种类型的指针,甚至不区分指针和整数。

程序存储器(program memory)包含:程序的可执行机器代码,操作系统需要的一些信息,用来管理过程调用和返回的运行时栈,以及用户分配的存储器块。同时OS负责管理虚拟地址空间,将虚拟地址转换为物理地址。

一条指令只执行一个非常基本的操作。例如,将存放在寄存器中的两个数字相加,在存储器和寄存器之间传送数据,或是条件分支转移到新的指令地址。编译器必须产生这些指令的序列,从而实现(像算术表达式求值、循环或过程调用和返回这样的)程序结构。

A key lesson to learn from this is that the program executed by the machine is simply a sequence of bytes encoding a series of instructions.

理解机器码的方式为反汇编(disassemblers),例如objd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值