最新公告
  • 欢迎您光临欧资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 内存中是如何存储指令和数据?、add指令你应该知道

    在之前的文章中,我们主要讲了一些基本的汇编指令,通过一个叫做Debug的调试软件,让我们看看指令和数据是如何存储在内存中的。学习了这些,我们就可以理解汇编程序了。.

    程序执行

    首先,我将通过示意图向大家介绍程序的执行过程。我们以一个简单的 C 语言 hello.c 程序为例。

    这是一个完整的hello world程序执行过程,涉及到几个核心组件:预处理器、编译器、汇编器和链接器。让我们一一分解。

    汇编语言非常有用,因为它可以为不同的高级语言提供自己的一套标准输出语言。

    所以,一般来说,一个可执行文件包括两个方面

    程序和数据,这些是构成可执行文件的基本信息。相关的描述信息,比如有多少空间,程序有多大等等,这些都是形成可执行文件的必要因素。了解汇编程序

    同样,我们先从一个汇编代码开始,然后在下面慢慢勾勒出来。

    assume cs:code
    code segment
    		mov ax,1234H
    		add ax,ax
    		mov bx,1111H
    		add bx,bx
    code ends
    end
    

    这段汇编代码中有几个地方你可能不是很了解,但是你应该知道mov和add指令是什么意思(如果你阅读了作者之前的文章并仔细研究过的话)。

    组成汇编程序的指令分为两种:一种是汇编指令,另一种是伪指令。汇编指令就是我们上面提到的 mov 和 add 指令。这些说明具有实际意义。例如,mov 是一个移动寄存器或数据。add 是寄存器或数据的添加。而且,mov、add等汇编指令在内存中都有对应的机器码,最终会被CPU执行。伪指令没有实际意义。他们只是定义了一个程序段。这些伪指令将由编译器直接解释。它们在内存中没有对应的机器码,因此它们不会被 CPU 执行。

    上面提到了三个伪指令,即

    code segment
    	......
    code ends
    

    Segment和ends是一组成对出现的指令,而这对指令必须成对出现,没有任何人。这对指令定义了一个段,段标识段的开始,结束标识段的结束。code代表段名,段名可以随意替换。

    汇编器由多个段(至少一个段)组成,用于存储代码、数据或作为堆栈空间。上面示例代码中的段是由代码组成的,所以称为代码段。

    除了段之外,汇编器还需要有assert,这也是一条伪指令,意思是假设它假设某段寄存器与某段有关联,而关联通过assert来解释。假设没有深入了解,我们只需要在编程时知道特定用途段与相关寄存器相关联即可。

    end 是汇编程序结束的标志。它也是一个伪指令。在编译汇编器的过程中,编译器遇到 end 时会停止编译。因此,如果我们完成了汇编程序的编写,我们需要将它添加到程序的末尾。end ,表示程序结束。

    在汇编器中,除了汇编指令和伪指令之外,还有一个标号,比如上面代码中的代码,标号位于段的前面,作为段的名称,本段的名称段最终将被编译并链接为段。段地址。

    提醒一下,注意不要在这里混淆 end 和 ends 。Ends 与segment 一起使用,表示组装段,end 是组装结束标志。

    综上所述,用汇编语言编写的源程序包括伪指令和汇编指令。伪指令由编译器执行,汇编指令可以翻译成机器码,最终由CPU执行。

    以后我们可以将源程序文件中的内容称为源程序,将源程序中最终由计算机执行和处理的指令或数据称为程序。程序首先以汇编指令的形式存在于原程序中,经过编译链接后转换为机器码,存入可执行文件中,如下图所示

    所以,总结起来,写一个汇编程序主要分为以下几个步骤

    程序返回

    一个完整的程序必须有一个返回条件。只有在程序执行完相关代码,执行返回条件并放弃CPU执行权后,操作系统才会将时间片分配给其他程序。程序不能总是占用 CPU。这是一种资源的浪费,不断的占用CPU,也会导致程序崩溃。

    在汇编语言中,实现程序返回只有两行指令

    mov ax,4c00H
    int 21H
    

    解释这两个命令的含义:

    mov ax,4c00H是将4c00移动到ax,in,INT 21H是调用系统中断指令,这两个代码的作用是AH = 4CH,表示调用INT 21H的4CH中断,中断是退出程序安全。

    至此,我们已经了解了与结束相关的几件事情,比如段结束,汇编结束,以及我们刚才说的程序返回。下表列出了这三个指令之间的区别。

    程序错误

    一般来说,汇编语言中的程序错误有两种:语法错误和逻辑错误。

    语法错误很简单。说白了就是你的汇编语言指令错误c语言有哪些伪指令,编译的时候可以找到程序。

    逻辑错误发生在运行时,一般不容易发现,也难以排查。比如下面的代码如果没有写程序返回,就是逻辑错误。

    assume cs:code
    code segment
    		mov ax,1234H
    		add ax,ax
    		mov bx,1111H
    		add bx,bx
    code ends
    end
    

    为什么?因为这段代码没有添加程序返回逻辑。类似的逻辑错误还有很多,这些错误需要在具体场景中发现。

    写汇编

    接下来,我们开始使用编辑器编写汇编源程序,只要将汇编存储为文本文件,然后通过编译器进行编辑,CPU就可以运行了。

    我们可以使用多种文本格式来编写汇编程序,例如我们可以使用最简单的文本文件来编写(基于win7操作系统环境)

    assume cs:codeseg
    codeseg segment
    		mov ax,0123H
    		mov bx,0456H
    		add ax,bx
    		add ax,ax
    codeseg ends
    end
    

    写入后,它会存储为 .asm 后缀文件,这是一种汇编格式。

    编译

    一个完整的汇编程序执行过程分为编写、编译、链接和运行,所以接下来我们需要编译编译好的汇编程序。在编译之前,我们需要找到对应的编译器,这里我们使用masm5.0汇编编译器,执行程序是masm.exe。

    (为了不让大家从网站上找资源,我下载下来放到网盘里,可以在程序员cxuan后台回复masm获取)

    说到使用masm5.0的过程,踩过不少坑。这里提醒大家及时收坑!!!

    masm 5.0是稳定版,网上流传的6.x不知道怎么弄的,没跑成功。masm 5.0 在win7环境下运行,我用win11测试,程序不兼容,不知道其他版本怎么样。win7版本运行良好。

    安装完成后,我们打开cmd,进入下载解压后的masm5.0文件夹。

    然后直接输入masm

    masm运行后会先显示一些版本信息,然后输入要编译的原程序文件名,这里需要注意,[.ASM]提醒我们默认文件扩展名是asm,比如我们要编译的源程序文件名称为test.asm,这里可以直接输入asm。如果源程序文件不以.asm为后缀,则需要输入其全名,即test.txt。

    这里我们进入test,因为我们写的文件有一个.asm后缀。

    输入源程序文件名后,按回车键,程序会提示我们输入要编译的目标文件名,目标文件名就是源程序编译的最终结果。Object文件名的后缀是.obj,因为.asm文件会自动编译成.obj文件,所以我们不需要指定文件名,直接回车,就生成了.obj文件直接地。

    目标文件名确定后,会出现Source列表,提示我们输入列表文件的名称。这个文件是编译器在将源程序编译成目标文件的过程中产生的中间结果,可以防止编译器生成这个文件,直接回车即可。如果编译器要生成这个文件,它的扩展名是.lst。

    然后继续提示Cross-reference,提示我们输入交叉引用文件的名称。该文件与 Source 列表一样,是编译器生成的中间结果。我们可以阻止编译器生成这个文件,我们可以直接回车。如果编译器要生成这个文件,它的扩展名是.crf。

    最后,编译器将输出一个结果,该结果将显示警告错误和必须纠正的错误。从上图可以看出,我们的程序没有任何警告和编译错误。

    输入源程序的文件名时,指出路径。如果遇到“无法打开输入文件”的问题,最好将汇编程序直接放在C盘。我放在桌面上c语言有哪些伪指令,也就是C:UsersAdministratorDesktop下也会出现这个错误。

    连接

    编译源程序得到目标文件后,我们需要连接目标文件得到可执行文件。我们在上一步中得到了 .obj 文件,现在我们需要将 .obj 文件链接到一个可执行文件 .exe 中。

    为了实现我们的需求,我们需要使用微软的Overlay Linker3.60连接器,文件名为link.exe,这个应用程序不需要再次下载(我公众号回复中获得的软件会包含编译器和连接器,解压后都在masm文件夹中)。

    现在我们进入 DOS,cd 进入 masm 文件,然后输入链接。

    运行链接后,会出现一些版本信息,然后会提示要链接的目标文件的名称。注意默认文件以.obj结尾,所以如果你需要链接的文件是obj文件,则不需要输入后缀名。如果不是 obj 文件,则需要输入全名。

    我们刚刚编译了一个 test.obj 文件,所以我们直接链接到 obj 文件。

    输入要链接的文件名(这里还是要输入obj所在的路径),回车。

    输入回车后,会继续出现三行提示。

    第一个提示表示程序继续提示我们输入要生成的可执行文件的名称。可执行文件就是我们想通过连接一个程序得到的最终结果。默认的.exe文件是TEST.EXE,所以我们不再需要指定文件名。这里也可以指定生成可执行文件的目录,我们不需要,继续往下。

    第二个提示是链接器提示输入图像文件的名称。该文件是链接器将目标文件链接成可执行文件的中间结果。您还可以使链接器不生成此文件并继续向下。

    第三个提示是链接器提示输入库文件的名称。库文件包含一些可以调用的子程序。如果程序调用库中的子程序,则需要指定,否则不需要。

    最后,警告:不会出现堆栈段。一直以为出现这个提示的时候不会生成最终的执行文件,但是仔细查看后发现,这只是个废话,最终的执行文件在masm文件夹下。我拍张照片给你看看。

    这个提示只是告诉我们没有栈段,我们可以完全忽略这个提示,当然如果你的程序有问题,连接后的文件是无法生成的。

    连接过程非常有用。简而言之,主要有三个功能。

    执行应用程序

    现在我左手有一个asm文件,右手有一个obj文件,嘴里有一个exe文件,所以我是口中之王越狱。折腾了半天,终于把asm变成了exe文件。我累了,别急着休息,还有最后一步,执行吧!

    所以我们执行下面的TEST.EXE文件

    我有点疑惑,为什么什么都没有,输出结果是什么?. . . . . .

    想了想,哦,我们没有使用任何库来向控制台输出信息,我们只是做了一些数据和寄存器移动和添加。

    当然我们可以将信息输出到控制台,但我们稍后会演示。

    简单说一下程序的加载过程

    我们都知道,如果要执行一个程序,就需要将它加载到内存中,然后CPU从内存中取出指令来执行命令。

    那么,当我们使用 DOS 时,谁负责将可执行程序加载到内存中呢?

    在DOS中,有一个东西叫命令解释器command.com,它也是DOS系统的外壳。

    DOS启动后会先初始化,然后运行command.com。command.com 运行后,执行其他相关任务后,屏幕上会显示提示,等待用户输入。

    如果用户输入了要执行的命令,比如cd、taskkill等,这些命令都是通过command来执行的,执行完成后再等待用户输入。

    如果用户输入要执行的程序,command会通过文件名找到可执行文件,然后加载到内存中,设置CS:IP执行入口,然后command暂停操作,CPU执行程序. 程序执行完成后,返回命令,命令再次等待用户输入。

    因此,一个完整的汇编程序的执行过程如下。

    如果这篇文章写得好,对你有帮助,那就求个赞!

    站内大部分资源收集于网络,若侵犯了您的合法权益,请联系我们删除!
    欧资源网 » 内存中是如何存储指令和数据?、add指令你应该知道

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    欧资源网
    一个高级程序员模板开发平台

    发表评论