《汇编语言》——王爽 第六章 包含多个段的程序
前面的程序中,只有一个代码段。现在有一个问题是,如果程序需要用其他空间来存放数据,使用哪里呢?第5章中,我们讲到要使用一段安全的空间。我们说0:200~0:2FF是相对安全的,可这段空间的容量只有256个字节,如果我们需要的空间超过256个字节该怎么办呢?
在操作系统的环境中,合法地通过操作系统取得的空间都是安全的,因为操作系统不会让一个程序所用的空间和其他程序以及系统自己的空间相冲突。在操作系统允许的情况下,程序可以取得任意容量的空间。
程序取得所需空间的方法有两种,一是在加载程序的时候为程序分配,再就是程序在执行的过程中向系统申请。在我们的课程中,不讨论第二种方法。
加载程序的时候为程序分配空间,我们在前面已经有所体验,比如我们的程序在加载的时候,取得了代码段中的代码的存储空间。
6.1在代码段中使用数据
如何将这些数据存储在一组地址连续的内存单元中呢?我们可以用指令一个一个地将它们送入地址连续的内存单元中。
当可执行文件的程序被加载入内存时,这些数据也同时被加载入内存中。
引入start的目的:因为程序的入口处不是我们所希望执行的指令,如何让这个程序在编译后可以在系统中直接运行呢?我们可以在源程序中指明程序的入口所在。也就是start
在前面的课程中,我们已经知道在单任务系统中,可执行文件中的程序执行过程如下。
1 由其他的程序(Debug,command或其他程序)将可执行文件中的程序加载入内存
2 设置CS:iP指向程序的第一条要执行的指令(即程序的入口),从而使程序得以运行;
3 程序运行结束后,返回到加载者。
现在的问题是,根据什么设置CPU的CS:iP指向程序的第一条要执行的指令?这一点,是由可执行文件中的描述信息指明的。
当程序被加载入内存后,加载者从程序的可执行文件的描述信息中读到程序的入口地址,设置CS:IP。这样CPU就从我们希望的地址处开始执行。
归根结底,我们若要CPU从何处开始执行程序,只要在源程序中用“end 标号”指明就可以了。
6.2在代码段中使用栈
完成下面的程序,利用栈,将程序中定义的数据逆序存放:
我们定义这些数据的最终目的是,通过它们取得一定容量的内存空间。
6.4将数据,代码,栈放入不同的段
一个段的容量不能大于64KB,是我们在学习中所用的8086模式的限制,并不是所有的处理器都这样。
现在,程序中有多个段了,如何访问段中的数据呢?当然要通过地址,而地址是分为两部分的,即段地址和偏移地址。如何指明要访问的数据的段地址呢?在程序中,段名就相当于一个标号,它代表了段地址。
8086CPU不允许将一个数值直接送入段寄存器中。
我们不必深究assume的作用,只要知道需要用它将你定义的具有一定用途的段和相关的寄存器联系起来就可以了。
CPU中的CS:IP被设置指向这个入口,从而开始执行程序中的第一条指令。标号“start”在“code”段中,这样CPU就将code段中的内容当作指令来执行了。
总之,CPU到底如何处理我们定义的段中的内容,是当作指令执行,当作数据访问,还是当作栈空间,完全是靠程序中具体的汇编指令来设定的。