《程序是怎样跑起来的》——第10章 通过汇编语言了解程序的实际构成

一、汇编语言和本地代码
1、汇编语言和本地代码的关系:汇编语言和本地代码是一 一对应的关系。计算机CPU能直接解释运行只有本地代码(机器语言)程序。用C语言等编写的源代码,需要通过各自的编译器编译后,转换成本地代码。通过调查本地代码的内容,可以了解程序最终是以何种形式来运行的。
2、汇编语言:在各本地代码中,附带上表示其功能的英语单词缩写。这些缩写称为助记符,使用助记符的编程语言称为汇编语言。这样,通过查看汇编语言编写的源代码,就可以了解程序的本质了。
3、汇编器:即使是用汇编语言编写的源代码,最终也必须要转换成本地代码才能运行。负责转换工作的程序称为汇编器,转换这一处理本身称为汇编。在将源代码转换成本地代码这个功能方面,汇编器和编译器是同样的。
4、汇编程序:用汇编语言编写的源代码,和本地代码是一一对应的。因而,本地代码也可以反过来转换成汇编语言的源代码。持有该功能的逆变换程序称为反汇编程序,逆变换这一处理本身称为反汇编。
示例:汇编语言的源代码和本地代码是一一对应的

二、通过编译器输出汇编语言的源代码
1、除了将本地代码进行反汇编这一方法外,通过其他方式也可以获取汇编语言的源代码。大部分C语言编译器,都可以把利用C语言编写的源代码转换成汇编语言的源代码,而不是本地代码。利用该功能,就可以对C语言的源代码和汇编语言的源代码进行比较研究。
2、(1)通过解析可执行文件得到源代码的方式称为“反汇编”或“反编译”,也称为“反向工程”。市场上销售的软件程序等,有时会在其使用说明书中明确表明禁止反汇编及反编译
(2)AddNum函数仅仅返回两个参数值的相加结果。在实际的编程中,这种函数是不需要的。为了说明函数调用的机制,这里特意使用了这种简单的函数。
(3)在命今提示符上运行的程序中,main函数位于程序运行起始位置。而在Windows上运行的程序中,WinMain函数位于程序运行起始位置。程序运行起始位置也称为“入口点”。
三、汇编语言的语法
1、概念:汇编语言指令的语法结构是操作码+操作数(也存在只有操作码没有操作数的指令)。
2、操作码和操作数:操作码表示的是指令动作,操作数表示的是指令对象。能够使用何种形式的操作码,是由 CPU 的种类决定的。操作数中指定了寄存器名、内存地址、常数等。
3、操作码的功能:

在汇编语言中,类似于mov这样的指令称为“操作码”(opcode),作为指令对象的内存地址及寄存器称为“操作数”(operand)。被转换成CPU可以直接解析运行的二进制的操作码和操作数,就是本地代码。
4、CPU和内存的关系:

本地代码加载到内存后才能运行。内存中存储着构成本地代码的指令和数据。程序运行时,CPU会从内存中把指令和数据读出,然后再将其存储在CPU内部的寄存器中进行处理。
5、x86系列CPU的主要寄存器:

寄存器是CPU中的存储区域。不过,寄存器并不仅仅具有存储指令和数据的功能,也有运算功能。寄存器的名称会通过汇编语言的源代码指定给操作数。内存中的存储区域是用地址编号来区分的。CPU内的寄存器是用eax及ebx 这些名称来区分的。此外,CPU内部也有程序员无法直接操作的寄存器。
四、函数
1、函数调用机制:在函数的入口处把寄存器ebp的值入栈保存,在函数的出口处出栈,这是C语言编译器的规定。这样做是为了确保函数调用前后cbp寄存器的值不发生变化。
示例:
(1)函数调用的汇编语言代码

(2)AddNum 函数调用前后栈的状态变化

2、函数内部的处理

AddNum函数内部的栈状态变化:

posted @ 2024-02-23 19:20  加克  阅读(7)  评论(0编辑  收藏  举报