【汇编语言】第一个程序(二)—— 带你真正了解一个源程序的结构是怎样的

news2024/11/24 21:07:14

在这里插入图片描述

文章目录

  • 前言
  • 1. 示例程序
  • 2. 伪指令
    • 2.1 XXX segment
    • 2.2 end
    • 2.3 assume
  • 3. 源程序中的“程序”
  • 4. 标号
  • 5. 程序的结构
  • 6. 程序返回
  • 7. 语法错误和逻辑错误
  • 结语

前言

📌

汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优化方面有重要作用。此外,它在逆向工程和安全领域不可或缺,帮助分析软件运行机制并增强漏洞修复能力。

本专栏的汇编语言学习章节主要是依据王爽老师的《汇编语言》来写的,和书中一样为了使学习的过程容易展开,我们采用以8086CPU为中央处理器的PC机来进行学习。

1. 示例程序

下面就是一段简单的汇编语言源程序。

assume cs:codesg

codesg segment
	mov ax, 0123H
	mov bx, 0456H
	add ax,bx
	add ax ax
	
	mov ax,4C00H
	int 21H

codesg ends

end

2. 伪指令

在汇编语言源程序中,包含两种指令,一种是汇编指令,一种是伪指令

  • 汇编指令是有对应的机器码的指令,可以被编译为机器指令,最终为CPU所执行。

  • 而伪指令没有对应的机器指令,最终不被CPU所执行。

那么谁来执行伪指令呢?伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作。

你现在能看出来最开始示例程序中哪些指令是伪指令吗?

示例程序中出现了3种伪指令,如下分析。

2.1 XXX segment

XXX segment
		:
		:
		:
xxx ends

segment 和ends是一对成对使用的伪指令,这是在写可被编译器编译的汇编程序时,必须要用到的一对伪指令。

segment和ends的功能是定义一个段,segment说明一个段开始,ends说明一个段结束。一个段必须有一个名称来标识,使用格式为:

段名 segment
	:
段名 ends

比如,示例代码中的:

codesg segment     ;定义一个段,段的名称为“codesg”,这个段从此开始
	:
codesg ends        ;名称为“codesg”的段到此结束

一个汇编程序是由多个段组成的,这些段被用来存放代码、数据或当作栈空间来使用。我们在前面的文章中所讲解的段的概念,在汇编源程序中得到了应用与体现,一个源程序中所有将被计算机所处理的信息:指令、数据、栈,被划分到了不同的段中。

一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。

我们可以看到,程序中,在codesg segmentcodesg ends之间写的汇编指令是这个段中存放的内容,这是一个代码段(其中还有我们不认识的指令,后面会进行讲解)。

2.2 end

end 是一个汇编程序的结束标记,编译器在编译汇编程序的过程中,如果碰到了伪指令end,就结束对源程序的编译。所以,在我们写程序的时候,如果程序写完了,要在结尾处加上伪指令end。否则,编译器在编译程序时,无法知道程序在何处结束。

❗注意,不要搞混了end和ends,ends是和segment 成对使用的,标记一个段的结束,ends的含义可理解为“end segment”。我们这里讲的 end 的作用是标记整个程序的结束。

2.3 assume

这条伪指令的含义为“假设”。它假设某一段寄存器和程序中的某一个用segment...ends定义的段相关联。通过 assume 说明这种关联,在需要的情况下,编译程序可以将段寄存器和某一个具体的段相联系。

assume并不是一条非要深入理解不可的伪指令,以后我们编程时,记着用assume将有特定用途的段和相关的段寄存器关联起来即可。

比如,在示例程序中,我们用 codesg segment .. codesg ends 定义了一个名为codseg的段,在这个段中存放代码,所以这个段是一个代码段。在程序的开头,用assume cs:codesg将用作代码段的段codesg和CPU中的段寄存器cs联系起来。

3. 源程序中的“程序”

用汇编语言写的源程序,包括伪指令汇编指令,我们编程的最终目的是让计算机完成一定的任务。源程序中的汇编指令组成了最终由计算机执行的程序,而源程序中的伪指令是由编译器来处理的,它们并不实现我们编程的最终目的。

这里所说的程序就是指源程序中最终由计算机执行、处理的指令或数据。

❗注意,以后可以将源程序文件中的所有内容称为源程序,将源程序中最终由计算机执行、处理的指令或数据,称为程序程序最先以汇编指令的形式存在源程序中,经编译、连接后转变为机器码,存储在可执行文件中。这个过程如下图所示。

在这里插入图片描述

4. 标号

汇编源程序中,除了汇编指令和伪指令外,还有一些标号,比如“codesg“一个标号指代了一个地址。比如codesg在segment的前面,作为一个段的名称,这个段的名称最终将被编译、连接程序处理为一个段的段地址

5. 程序的结构

我们现在讨论一下汇编程序的结构。在前面的学习中,我们都是通过直接在Debug中写入汇编指令来写汇编程序,对于十分简短的程序这样做的确方便。可对于大一些的程序,就不能如此了。我们需要写出能让编译器进行编译的源程序,这样的源程序应该具备起码的结构。

源程序是由一些段构成的。我们可以在这些段中存放代码、数据、或将某个段当作栈空间。我们现在来一步步地完成一个小程序,从这个过程中体会一下汇编程序中的基本要素和汇编程序的简单框架。

任务:编程运算2^3。源程序应该怎样来写呢?

(1)我们要定义一个段,名称为abc。

abc segment
	:
abc ends

(2)在这个段中写入汇编指令,来实现我们的任务。

abc segment
	mov ax, 2
	add ax, ax
	add ax, ax
abc ends

(3)然后,要指出程序在何处结束。

abc segment
	mov ax, 2
	add ax, ax
	add ax, ax
abc ends

end

(4)abc被当作代码段来用,所以,应该将abc和cs联系起来。(当然,对于这个程序,也不是非这样做不可。)

assume cs:abc
abc segment
	mov ax, 2
	add ax, ax
	add ax, ax
abc ends

end

最终这样一个汇编源程序就被我们完成了。

6. 程序返回

我们的程序最先以汇编指令的形式存在源程序中,经编译、连接后转变为机器码,存储在可执行文件中,那么,它怎样得到运行呢?

下面,我们在DOS(一个单任务操作系统)的基础上,简单地讨论一下这个问题
一个程序P2在可执行文件中,则必须有一个正在运行的程序P1,将P2从可执行文件中加载入内存后,将CPU的控制权交给P2,P2才能得以运行。P2开始运行后,P1暂停运行。

而当P2运行完毕后,应该将CPU的控制权交还给使它得以运行的程序P1,此后,P1继续运行。

现在,我们知道,一个程序结束后,将CPU的控制权交还给使它得以运行的程序,我们称这个过程为:程序返回。那么,如何返回呢?应该在程序的末尾添加返回的程序段。

我们回过头来,看一下最开始示例程序中的两条指令:

mov ax,4C00H
int 21H

这两条指令所实现的功能就是程序返回。

在目前阶段,我们不必去理解int 21H指令的含义,和为什么要在这条指令的前面加上指令 mov ax, 4c00H。我们只要知道,在程序的末尾使用这两条指令就可以实现程序返回。

到目前为止,我们已经遇到了几个和结束相关的内容:段结束、程序结束、程序返回。下表展示了它们的区别。

目的相关指令指令性质指令执行者
通知编译器一个段结束段名 ends伪指令编译时,由编译器执行
通知编译器程序结束end伪指令编译时,由编译器执行
程序返回mov ax, 4c00H int 21H汇编指令执行时,由CPU执行

7. 语法错误和逻辑错误

可见,在上面我们自己实现任务的程序在运行时会引发一些问题,因为程序没有返回。当然,这个错误在编译的时候是不能表现出来的,也就是说,该程序对于编译器来说是正确的程序。

一般说来,程序在编译时被编译器发现的错误是语法错误

比如将程序写成如下这样就会发生语法错误:

aume cs:abc

abc segment
	mov ax, 2
	add ax, ax
	add ax, ax

end

显然,程序中有编译器不能识别的aume,而且编译器在编译的过程中也无法知道 abc段到何处结束。

在源程序编译后,在运行时发生的错误是逻辑错误。语法错误容易发现,也容易解决。而逻辑错误通常不容易被发现。

不过,最后完成的任务程序中的错误却显而易见,没有加程序返回,我们将它改正过来:

assume cs:abc
abc segment
	mov ax, 2
	add ax, ax
	add ax, ax
	
	mov ax,4C00H
	int 21H
abc ends

end

结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2224688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu22 安装labelimg制作自己的深度学习目标检测数据集

参考文章:目标检测---利用labelimg制作自己的深度学习目标检测数据集-CSDN博客 以上文章是windows下使用的方法,本章是在ubuntu22下使用的方法 一、准备工作 确保您的Ubuntu系统已安装Python 3.7或更高版本。可以通过在终端输入 python3 --version 来检…

2024 BuildCTF 公开赛|MISC

1.what is this? BuildCTF{S0_TH1S_15_M0R5E_C0DE_!!} 2.一念愚即般若绝,一念智即般若生 解压缩密码:s2j6dg* BuildCTF{D3crypt10n_1s_4_l0ng_r04d} 3.如果再来一次,还会选择我吗? 修复png 密码:8!67adz6&#xff…

二进制方式部署k8s集群

目标任务: 1、Kubernetes集群部署架构规划 2、部署Etcd数据库集群 3、在Node节点安装Docker 4、部署Flannel网络插件 5、在Master节点部署组件(api-server,schduler,controller-manager) 6、在Node节点部署组件(kubelet,kube-proxy) 7、查看集群状态 8、运行⼀个测…

springboot087植物健康系统(论文+源码)_kaic

植物健康系统 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了植物健康系统的开发全过程。通过分析植物健康系统管理的不足,创建了一个计算机管理植物健康系统的方案。文章介绍了植物健康系统的系统…

web3对象如何连接以太网络节点

实例化web3对象 当我们实例化web3对象,我们一般开始用本地址,如下 import Web3 from web3 var web3 new Web3(Web3.givenProvider || ws://localhost:5173)我们要和以太网进行交互,所以我们要将’ws://localhost:5173’的本地地址换成以太…

哪些CRM系统适合医疗行业?主流10款产品全解析

本文介绍了10款crm系统:纷享销客、Zoho CRM、海创CRM、红云CRM、慧影CRM、易华录CRM、用友健康CRM、Highrise CRM、Maximizer CRM、Infusionsoft by Keap。 在医疗行业中,选择合适的客户关系管理(CRM)系统可能是一项令人头疼的挑战…

fastGpt

参考本地部署FastGPT使用在线大语言模型 1 rockylinx 1 ollama安装 在rockylinux中安装的,ollama由1.5G,还是比较大,所有采用在windows下下载,然后安装的方式,linux安装 tar -C /usr -xzf ollama-linux-amd64.tgz #…

Vue3学习:汇率计算器案例中event.target与event.currentTarget比较

今天从一本vue.js书中学习了《汇率计算器》的案例,这个案例的效果如下: 案例可以查询人民币、日元、港元、美元、欧元之间的汇率关系,代码中定义了一个汇率表rate,包含了每种货币对其他5种货币的汇率。其中还有一个功能是点击下方…

WPF的触发器(Trigger)

WPF(Windows Presentation Foundation)是微软.NET框架的一部分,用于构建Windows客户端应用程序。在WPF中,触发器(Triggers)是一种强大的功能,允许开发者根据控件的状态或属性值来动态改变控件的…

Zabbix 监控自动化

一、网络自动发现 部署环境 zabbix server ZBX 192.168.27.152 CentOS7.9 zabbix server 6.4.8 zabbix agent agent01 192.168.27.154 CentOS7.9 zabbix agent 6.4.8 zabbix agent agent02 192.168.27.158 CentOS7.9 zabbix agent 6.4.8 1.搭建LNMP环境 2.安装配…

Http 状态码 301 Permanent Rediret 302 Temporary Redirect

HTTP状态码301和302是什么? 1、HTTP状态码301 HTTP状态码301表示永久性转移(Permanent Redirect),这意味着请求的资源已经被分配了一个新的URI,以后的引用应该使用资源现在所指的URI。 HTTP 301状态码表示请求的资源…

力扣刷题(sql)--零散知识点(1)

通过一段时间的刷题,感觉自己的sql能力逐渐上去,所以不会像前三道题一样讲那么详细了,这里主要会讲到一些特殊的知识点和方法。另外,我的建议是做完一个题有好的想法赶紧记录下来,不要想着最后汇总,不然会懒…

STATCOM静止同步补偿器原理及MATLAB仿真模型

STATCOM原理简述 整个STATCOM 装置相当于一个电压大小可以控制的电压源。当控制 STATCOM 装置产生的电压小于系统电压即UI<US 时&#xff0c;STATCOM 装置向系统输出的无功功率Q<0&#xff0c;此时 STATCOM 装置相当于电感&#xff1b;当控制 STATCOM 装置产生的电压大于…

编写一个简单的Iinput_dev框架

往期内容 本专栏往期内容&#xff1a; input子系统的框架和重要数据结构详解-CSDN博客input device和input handler的注册以及匹配过程解析-CSDN博客input device和input handler的注册以及匹配过程解析-CSDN博客 I2C子系统专栏&#xff1a; 专栏地址&#xff1a;IIC子系统_憧憬…

理工科考研想考计算机,湖南大学、重大、哈工大威海、山东大学,该如何选择?

C哥专业提供——计软考研院校选择分析专业课备考指南规划 计算机对理工科同学来说&#xff0c;还是性价比很高的&#xff0c;具有很大的优势&#xff01; 一、就业前景广阔 高需求行业 在当今数字化时代&#xff0c;计算机技术几乎渗透到了各个领域&#xff0c;无论是互联网…

在MacOS玩RPG游戏 - RPGViewerPlus

背景知识 由于我一直使用Mac电脑&#xff0c;所以一直对Mac如何玩RPGMV/RPGMZ游戏的方式有进一步的想法。 网上能给出的方案都是自行启动一个HTTP服务进行&#xff0c;进行服务加载。这个方法有效&#xff0c;但兼容性较差。涉及到自定义功能模块的游戏&#xff0c;都会有报错…

十分钟Linux中的epoll机制

epoll机制 epoll是Linux内核提供的一种高效I/O事件通知机制&#xff0c;用于处理大量文件描述符的I/O操作。它适合高并发场景&#xff0c;如网络服务器、实时数据处理等&#xff0c;是select和poll的高效替代方案。 1. epoll的工作原理 epoll通过内核中的事件通知接口和文件…

FlinkSQL之temporary join开发

在实时开发中&#xff0c;双流join获取目标对应时刻的属性时&#xff0c;经常使用temporary join。笔者在流量升级的实时迭代中&#xff0c;需要让流量日志精准的匹配上浏览时间里对应的商品属性&#xff0c;使用temporary join开发过程中踩坑不少&#xff0c;将一些经验沉淀在…

Flutter鸿蒙next 中如何实现 WebView【跳、显、适、反】等一些基础问题

✅近期推荐&#xff1a;求职神器 https://bbs.csdn.net/topics/619384540 &#x1f525;欢迎大家订阅系列专栏&#xff1a;flutter_鸿蒙next &#x1f4ac;淼学派语录&#xff1a;只有不断的否认自己和肯定自己&#xff0c;才能走出弯曲不平的泥泞路&#xff0c;因为平坦的大路…

使用C#学习Office文件的处理(pptx docx xlsx)

Office文件 是指PPT 、word、Excel 这些常用工具生成的文件 &#xff0c;例如 pptx docx xlsx。 这些文件的读取和生成有很多很多库 例如 NOPI 、DevExpress、C1、Aspose、Teleric 等等&#xff0c;各有各的优缺点。俺今天不讲这个&#xff0c;俺只是讲讲如何了解Office文件的…