电子说
在前面的文章中我们多次提到,计算机CPU
能直接解释运行的只有 「本地代码」 (机器语言)程序。用C语言
等编写的源代码,需要通过各自的 「编译器」 编译后,转换成本地代码。
通过调用本地代码的内容,可以了解程序最终是以何种形式来运行的。但是,直接打开本地代码来看,只能看到数值的罗列。
我们可以采用另外一种方式,在各本地代码中,附带上表示其功能的英语单词缩写。例如,在加法运算的本地代码中加上add
、在比较运算的本地代码中加上cmp
等。这些缩写被称为 「助记符」 ,使用助记符的编程语言称为**「汇编语言」**
不过, 「即使是用汇编语言编写的源代码,最终也必须要转换成本地代码才能运行」 。负责准换工作的程序称为 「汇编器」 ,转换这个一处理本身称为 「汇编」 。
❝用汇编语言编写的源代码,和本地代码是一一对应的
❞
本地代码也可以反过来转换成汇编语言的源代码。持有该功能的 「逆变换」 程序称为 「反汇编程序」 ,逆变换这一处理本身称为 「反汇编」 。
汇编语言的源代码,是由转换本地代码的指令和针对汇编器的 「伪指令」 构成的。 「伪指令负责把程序的构造及汇编的方法指示给汇编器(转换程序)」 。不过,伪指令是无法汇编转换成本地代码。
如上是一个汇编代码片段。其中 「彩色」 部分是伪指令。
由伪指令segment
和ends
围起来的部分,是给构成程序的命令和数据的集合体加上一个名字而得到的,称为 「段定义」 。段定义的英文表达segment
具有区域的意思。在程序中, 「段定义指的是命令和数据等程序的集合体的意思」 。
❝一个程序由多个段定义构成
❞
如上图所示。源代码的开始位置,定义了3个名称分别为_TEXT
、_DATA
、_BSS
的段定义。
_TEXT
是指令的段定义_DATA
是被初始化(有初始值)的数据的段定义_BSS
是尚未初始化的数据的段定义而这些段定义的名称及划分方法,不同的编译器都有自己的一套规则。
伪指令proc
和endp
围起来的部分,表示的是过程Proceduce的范围。在汇编语言中,这种相当于C
语言的函数的形式称为过程。
「在汇编语言中,1行表示对CPU
的一个指令」 。汇编语言指令的语法结构是 「操作码」 + 「操作数」 。
操作码和操作数罗列在一起的语法,就是一个英文的指令文本。操作码是动词,操作数相当于宾语。
能够使用何种形式的操作码,是由CPU
的种类决定的。
常用操作码的功能
本地代码加载到内存后才能运行。内存中存储着构成本地代码的指令和数据。程序运行时,CPU
会从内存中把指令和数据读出,然后再将存储在CPU
内部的寄存器中进行处理。
「寄存器是CPU
中的存储区域」 。不过,寄存器并不仅仅具有存储指令和数据的功能,也有运算功能。寄存器的名称会通过汇编语言的源代码指定给操作数。内存中的存储区域是用 「地址编号」 来区分的。CPU
内的寄存器是用eax
及ebx
这些名称开区分的。
下图是CPU
的寄存器的主要种类和角色
mov
指令的两个操作数,分别是用来指定数据的 「存储地」 和 「读出源」 。
操作数可以指定寄存器、常数、标签(附近在地址前)以及用方括号([]
)围起来的这些内容。
mov ebp,esp;
mov eax,dword ptr [ebp+8];
mov ebp,esp
中,esp
寄存器中的值被直接存储在ebp
寄存器中。esp
寄存器的值是100
时ebp
寄存器的值也是100
。
而mov eax,dword ptr [ebp+8];
中,ebp
寄存器的值加8后得到的值会被解释为内存地址。如果ebp
寄存器的值是100的话,那么eax
寄存器中存储的就是100 + 8 = 108
地址的数据。
全部0条评论
快来发表一下你的评论吧 !