程序是怎样跑起来的(10)

通过汇编汉语言了解程序的实际构成
汇编语言和本地代码是一一对应的。通过调查本地代码的内容,可以了解程序最终是以何种形式来运行的。但是如果直接打开本地代码来看的话,只能看到数值的罗列。如果直接使用这些数值来编写程序的话,很难看懂。然后就产生了一种想法,在各本地代码中附带上表示其功能的英语单词缩写。这些缩写称为助记符,使用助记符的编程语言称为汇编语言。
通过汇编语言编写的源代码,就可以了解程序的本质了。这和查看本地代码的以源代码是同一级别的。即使是用汇编语言编写的源代码,也是必须要转换成本地代码才能运行。负负责转换工作的程序成为汇编器,转换这一处理本身称为汇编。将源代码转换成本地代码这个功能上,汇编器和编译器是同样的。
用汇编语言别写的源代码,和本地代码是一一对应的。因为本地代码也可以反过来转换成汇编语言的源代码。持有该功能的逆变转换程序成为反汇编程序,逆变换着一处理本身称为反汇编。而c语言的源代码的反编译是非常困难的。因为c语言的源代码与本地底代码不是一一对应的,所以想还原到原始的源代码是不太可能的。
通过编译器输出汇编语言的源代码,大部分c语言的编译器都可以把c语言编写的源代码转换成汇编语言的源代码,而不是本地代码。书中说汇编语言比c语言还要简单,这个目前不了解有待求证。
汇编语言的源代码,是由转换成本地代码的指令和针对汇编器的伪指令构成的。伪指令负责把程序的构造及汇编的方法指示给汇编器。伪指令本身是无法汇编转换成本地代码的。
汇编语言的语法是“操作码”+“操作数”
操作码标表示的是指令动作,操作数表示的是指令对象。操作码和操作数罗列在一起的语法,就是一个英文的指令文本。能用什么类型的操作码是由CPU的种类决定的,操作数中指定了寄存器名、内存地址、常数等。
本地代码加载到内存后才能运行。内存中存储着构成本地代码的指令和数据。程序运行时,CPU会从内存中把指令和数据读出。然以后再将其存储在CPU内部的寄存器中进行处理。
寄存器是CPU中的存储区域。寄存器并不仅仅具有存储指令和数据的功能,也有运算功能。
最常用的mov指令
指令中最常用的是对寄存器和内存进行数据存储的mov指令。mov指令的两个操作数,分别用来指定数据的存储地和读取源。操作数中可以指定寄存器、常数、标签、(附加在地址前),以及用方括号([])围起来的这些内容。如果指定了没有用方括号围起来的内容,就表示对该数值进行处理;如果指定了方括号围起来的内容,方括号中的值则会被解释为内存地址,然后就会对该内存地址对应的值进行读写操作。

对栈进行push和pop
程序运行时,会在内存上申请分配一个称为栈的数据空间。栈的数据在存储时是从内存的下层逐渐往上层累积的,读出时则是按照从上往下顺利进行的。栈是存储临时数据的区域,它的特点是通过push指令和pop指令进行数据的存储和读出。push指令和pop指令中只有一个操作数。

函数的参数是通过栈来传递,返回值是通过寄存器来返回的。

c语言中,在函数外部定义的变量称为全局变量,在函数内部定义的变量称为局部变量。全局变量可以参阅源代码的任意部分,而局部变量只能在定义该变量的函数内进行参阅。在_DSTA和_BSS的段定义中,全局变量的内存空间都得到了确保。从程序的开始到结束,所有部分都可以参阅全局变量。局部变量是临时保存在寄存器和栈中的。

posted @ 2024-02-28 11:49  ༺ཌ༈枫祁༈ད༻  阅读(1)  评论(0编辑  收藏  举报