首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【汇编语言】第一个程序(三)—— 深度剖析汇编程序的执行流程:编辑、编译、连接与运行

【汇编语言】第一个程序(三)—— 深度剖析汇编程序的执行流程:编辑、编译、连接与运行

作者头像
Crossoads
发布于 2024-10-30 00:32:34
发布于 2024-10-30 00:32:34
1.5K00
代码可运行
举报
文章被收录于专栏:汇编语言汇编语言
运行总次数:0
代码可运行

前言

📌 汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优化方面有重要作用。此外,它在逆向工程和安全领域不可或缺,帮助分析软件运行机制并增强漏洞修复能力。 本专栏的汇编语言学习章节主要是依据王爽老师的《汇编语言》来写的,和书中一样为了使学习的过程容易展开,我们采用以8086CPU为中央处理器的PC机来进行学习。

通过前面的学习我们已经知道一个汇编源程序应该是什么样的,本文我们将会从一个源程序的编辑到最终的运行完整的过程展现出来。

在本节中将要用到我们之前在 【汇编语言】寄存器(CPU工作原理)(七)—— 查看CPU和内存,用机器指令和汇编指令编程 这篇文章中所下载的软件和执行程序了。

1. 编辑源程序

可以用任意的文本编辑器来编辑源程序,只要最终将其存储为纯文本文件即可。在这里我们将用Notepad++来进行编辑程序,并且以如下程序作为示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

1.1 找到执行程序的目录

我们首先要找到当初下载的执行程序的目录,之后编辑好的源程序要放在该目录下才可以被执行,因为这样才能被执行程序所找到。

1.2 进入文本编辑器,编辑程序

在Notepad++中编辑程序,如下图所示。

1.3 保存源程序文件,推出编辑

将源程序文件保存在执行程序的目录下,比如说我这里是:D:\DOSBox\MASM\1.asm。(汇编源程序文件的后缀是.asm)

2. 启动DOS模拟器——DOSBox

2.1 执行挂载操作

首先打开DOSBox程序后,将我们执行程序的路径挂载到DOSBox的C盘上(这样就把我们的d盘里的这个执行程序所在的文件夹当作模拟器里面的C盘使用了)。

2.2 转换到C盘

将模拟器的当前位置转到模拟器的C盘上。

执行dir命令可以看当前位置下,我们所具备的文件和文件夹。

3. 编译

在我们得到一个源程序文件D:\DOSBox\MASM\1.asm后。可以对其进行编译,生成包含机器代码的目标文件。

在编译一个源程序之前首先要找到一个相应的编译器。我们这里就是使用的之前下载的文件名为masm.exe执行程序。

3.1 编译源程序

在执行文件的目录下,运行masm.exe。输入要编译的源程序文件名后,按Enter键,屏幕显示如下图所示。

上图中,在执行命令后,程序继续提示我们输入要编译出的目标文件的名称,目标文件是我们对一个源程序进行编译要得到的最终结果。

注意屏幕上的显示:“1.OBJ”,因为我们已经输入了源程序文件名为1.asm,则编译程序默认要输出的目标文件名为1.obj,所以可以不必再另行指定文件名。

直接按Enter键,编译程序将在当前的目录下,生成1.obj 文件。

3.2 忽略列表文件

确定了目标文件的名称后,屏幕显示如下图所示。

上图中,编译程序提示输入列表文件的名称,这个文件是编译器将源程序编译为目标文件的过程中产生的中间结果。可以让编译器不生成这个文件,直接按Enter键即可。

3.3 忽略交叉引用文件

忽略了列表文件的生成后,屏幕显示如下图所示。

上图中,编译程序提示输入交叉引用文件的名称,这个文件同列表文件一样,是编译器将源程序编译为目标文件过程中产生的中间结果。可以让编译器不生成这个文件,直接按 Enter 键即可。

3.4 编译结束的结果

忽略了交叉引用文件的生成后,屏幕显示如下图所示。

上图中,对源程序的编译结束,编译器输出的最后两行告诉我们这个源程序没有警告错误和必须要改正的错误。

上面我们通过对 C盘根目录下的 1.asm 进行编译的过程,展示了使用汇编编译器对源程序进行编译的方法。按照上面的过程进行了编译之后,在编译器masm.exe 运行的目录下(即当前路径下),将出现一个新的文件:1.obj,如下图所示,这是对源程序 1.asm 进行编译所得到的结果。当然,如果编译的过程中出现错误,那么将得不到目标文件。

一般来说,有两类错误使我们得不到所期望的目标文件:

  1. 程序中有“Severe Errors”
  2. 找不到所给出的源程序文件。

注意,在编译的过程中,我们提供了一个输入,即源程序文件。最多可以得到3个输出:目标文件(.obj)、列表文件(.lst)、交叉引用文件(.crf),这3个输出文件中,目标文件是我们最终要得到的结果,而另外两个只是中间结果,可以让编译器忽略对它们的生成。在汇编课程中,我们不讨论这两类文件。

4. 连接

在对源程序进行编译得到目标文件后,我们需要对目标文件进行连接,从而得到可执行文件。在这里我们需要使用到的可执行文件名为link.exe。

4.1 连接目标文件

仍然在执行文件目录下,运行link.exe。

上图中,在执行命令后,程序继续提示我们输入要生成的可执行文件的名称,可执行文件是我们对一个程序进行连接要得到的最终结果。注意屏幕上的显示:“1.EXE”,因为已经确定了目标文件名为1.obj,则程序默认要输出的可执行文件名为1.EXE,所以可以不必再另行指定文件名。

直接按Enter键,编译程序将在当前的目录下,生成 1.EXE 文件。

4.2 忽略映像文件

确定了可执行文件的名称后,屏幕显示如下图所示。

上图中,连接程序提示输入映像文件的名称,这个文件是连接程序将目标文件连接为可执行文件过程中产生的中间结果,可以让连接程序不生成这个文件,直接按Enter键即可。

4.3 忽略库文件

忽略了映像文件的生成后,屏幕显示如下图所示。

上图中,连接程序提示输入库文件的名称。库文件里面包含了一些可以调用的子程序,如果程序中调用了某一个库文件中的子程序,就需要在连接的时候,将这个库文件和目标文件连接到一起,生成可执行文件。

但是,这个程序中没有调用任何子程序,所以,这里忽略库文件名的输入,直接按Enter 键即可。

4.4 连接结束的结果

忽略了库文件的连接后,屏幕显示如下图所示。

上图中,对目标文件的连接结束,连接程序输出的最后一行告诉我们,这个程序中有一个警告错误:“没有栈段”,这里我们不理会这个错误。

上面我们通过对当前路径下的1.obj进行连接的过程,展示了使用连接器对目标文件进行连接的方法。按照上面的过程进行了连接之后,在连接器link.exe运行的目录下(即当前路径下),将出现一个新的文件:1.exe,如下图所示,这是对目标文件1.obj进行连接所得到的结果。当然,如果连接过程中出现错误,那么将得不到可执行文件。

4.5 连接的作用

连接的作用是什么呢?

对于连接,我们也不想过多地讨论。实际上,在汇编学习中,我们将会接触到许多知识、概念,对于这些,我们并不是都有深入讨论的必要。

这里再次强调一下,我们学习汇编的主要目的,就是通过用汇编语言进行编程而深入地理解计算机底层的基本工作机理,达到可以随心所欲地控制计算机的目的。基于这种考虑,我们的编程活动,大都是直接对硬件进行的。我们希望直接对硬件编程,却并不希望用机器码编程。我们用汇编语言编程,就要用到编辑器(Edit)、编译器(masm)、连接器(link)、调试工具(Debug)等所有工具,而这些工具都是在操作系统之上运行的程序,所以我们的学习过程必须在操作系统的环境中进行。我们在一个操作系统环境中,使用了许多工具,这势必要牵扯到操作系统、编译原理等方面的知识和原理。我们只是利用这些环境、工具来方便我们的学习,而不希望这些东西分散了我们的注意力。所以,对于涉及而又不在我们学习的主要内容之中的东西,我们只做简单的解释。

✍我们简单地讲一下连接的作用,连接的作用有以下几个。

  1. 当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序将它们连接到一起,生成一个可执行文件。
  2. 程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件。
  3. 一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理为最终的可执行信息。所以,在只有一个源程序文件,而又不需要调用某个库中的子程序的情况下,也必须用连接程序对目标文件进行处理,生成可执行文件。

❗注意,对于连接的过程,可执行文件是我们要得到的最终结果。

5. 简化编译和连接的过程

在前面的内容里,介绍了如何使用masm和link进行编译和连接。

可以看出,我们编译、连接的最终目的是用源程序文件生成可执行文件。在这个过程中所产生的中间文件都可以忽略。所以我们可以用一种较为简捷的方式进行编译、连接。

还是一样,需要在执行程序的目录下执行所有过程。

5.1 简捷的编译

过程如下图所示。

见上图可知,直接在masm后面加上被编译的源程序文件名,然后再加上分号,按Enter键后,编译器就对源程序文件进行编译,在当前路径下生成目标文件1.obj,并在编译的过程中自动忽略中间文件的生成。

5.2 简捷的连接

过程如下图所示。

见上图可知,直接在link 后面加上被连接的目标文件名,再加上分号,按Enter键后,连接程序就对当前路径下的1.obj进行处理,在当前路径下生成可执行文件1.exe,并在过程中自动忽略中间文件的生成。

6. 1.exe 的执行

现在,终于将我们的第一个汇编程序加工成了一个可在操作系统下执行的程序文件我们现在执行一下,下图展示了 1.exe 的执行情况。

奇怪吗?

程序运行后,竟然没有任何结果,就和没有运行一样。那么,程序到底运行了吗?

程序当然是运行了,只是从屏幕上不可能看到任何运行结果,因为,我们的程序根本没有向显示器输出任何信息。程序只是做了一些将数据送入寄存器和加法的操作,而这些事情,我们不可能从显示屏上看出来。程序执行完成后,返回,屏幕上再次出现操作系统的提示符。

当然,我们不能总是写这样的看不到任何结果的程序,随着之后的进一步学习,我们将会向显示器上输出信息,请大家耐心等待。

结语

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
多链支持,真没你想的那么简单
总算是空闲下来可以整理一下代码了,Web3项目接入多链钱包连接功能,主要涉及 Ethereum、Polygon、BSC 和 Solana。乍一听好像只是“多做几套兼容逻辑”的事,但真正落地后才发现,很多东西其实没想得那么简单。
阿珏
2025/07/06
540
以太坊交互工具
以太坊提供了Geth客户端用于管理API,我们可以在终端输入geth help查看其具体使用方法:
Al1ex
2021/07/21
1.9K0
以太坊交互工具
以太坊网络架构解析
区块链的火热程度一直以直线上升,其中以区块链 2.0 —— 以太坊为代表,不断的为传统行业带来革新,同时也推动区块链技术发展。
Seebug漏洞平台
2018/07/12
1.8K0
Derek解读Bytom源码-启动与停止
Gitee地址:https://gitee.com/BytomBlockchain/bytom
比原链Bytom
2018/08/30
5320
Derek解读Bytom源码-启动与停止
知道创宇区块链安全实验室|深入理解以太坊交易处理机制
区块链是一个以"去中心化"、"去信任化"方式集体维护的分布式账本,这里的"分布式"不仅体现在数据的分布式存储,也体现在数据的分布式记录,即由系统参与者共同维护,作为"账本"的区块链自然少不了记账,而交易自然而然的成为了重中之重。
Al1ex
2021/07/21
1.7K0
知道创宇区块链安全实验室|深入理解以太坊交易处理机制
理解以太坊: Go-Ethereum 源码剖析(0): Geth Start
Geth[2] 是基于 Go 语言开发以太坊的客户端,它实现了 Ethereum 协议(黄皮书)中所有需要的实现的功能模块,包括状态管理,挖矿,P2P 网络通信,密码学,数据库,EVM 解释器等。我们可以通过启动 Geth 来运行一个 Ethereum 的节点。Go-ethereum 是包含了 Geth 在内的一个代码库,它包含了 Geth,以及编译 Geth 所需要的其他代码。在本系列中,我们会深入 Go-ethereum 代码库,从 High-level 的 API 接口出发,沿着 Ethereum 主 Workflow,从而理解 Ethereum 具体实现的细节。
Tiny熊
2022/05/25
2.3K0
聊聊kingbus的binlog_server_handler.go
kingbus的binlog_server_handler提供了StartBinlogServer、StopBinlogServer、GetBinlogServerStatus,他们均委托给了server.go的对应方法
code4it
2020/06/18
3610
NFT+DeFi流动性挖矿系统开发策划细节
其简洁是得力于 Geth 使用了 gopkg.in/urfave/cli.v1 扩展包,该扩展包用于管理程序的启动,以及命令行解析,其中 app 是该扩展包的一个实例。
KFZ433
2022/06/17
3860
以太坊虚拟机(下篇)
区块链上的虚拟机(Virtual Machine)是指建立在去中心化的区块链上的代码运行环境,目前市面上比较主流的便是以太坊虚拟机(Ethereum Virtual Machine,EVM)和类以太坊虚拟机,它基于Account账户模型将智能合约代码以对外完全隔离的方式在内部运行,实现了图灵完备的智能合约体系,本篇文章将从源码角度对其工作原理进行简要分析~
Al1ex
2021/07/21
7260
以太坊RPC机制
RPC(remote process call),即远程过程调用,意思就是两台物理位置不同的服务器,其中一台服务器的应用想调用另一台服务器上某个应用的函数或者方法,由于不在同一个内存空间不能直接调用,因此需要通过网络来表达语义以及传入的参数,RPC是跨操作系统,跨编程语言的网络通信方式。
Al1ex
2021/07/21
3.8K0
以太坊RPC机制
以太坊多节点私有链部署
https://g2ex.github.io/2017/09/12/ethereum-guidance/
飞狗
2018/09/10
1.5K0
以太坊虚拟机(上篇)
区块链上的虚拟机(Virtual Machine)是指建立在去中心化的区块链上的代码运行环境,目前市面上比较主流的便是以太坊虚拟机(Ethereum Virtual Machine,EVM)和类以太坊虚拟机,它基于Account账户模型将智能合约代码以对外完全隔离的方式在内部运行,实现了图灵完备的智能合约体系,本篇文章将从源码角度对其工作原理进行简要分析~
Al1ex
2021/07/21
1.6K0
以太坊虚拟机(上篇)
交易所对接以太坊钱包服务设计与实现
交易所钱包服务是加密货币交易所系统中的重要组成部分,它负责与各种不同的区块链的交互,实现用户地址生成、充值与提现等功能。本文以对接以太坊区块链的钱包服务为例,介绍交易所系统平台中钱包管理服务的设计与实现。
用户1408045
2019/08/09
2.9K0
聊聊kingbus的starRaft
starRaft方法先通过rafthttp.NewRoundTripper创建http.RoundTripper,之后通过storage.NewDiskStorage创建DiskStorage,之后根据logExist及cfg.NewCluster做不同处理;若二者都为false则更新membership.RaftCluster的id为存在的cluster的id,然后执行startEtcdRaftNode;若cfg.NewCluster为true则使用cl.MemberIDs()来执行startEtcdRaftNode;若logExist为true则执行restartEtcdNode;最后创建rafthttp.Transport,执行tr.Start()、tr.AddRemote、tr.AddPeer
code4it
2020/06/13
4670
聊聊kingbus的starRaft
区块链开发(三)以太坊客户端命令行选项汇总
本篇博客的内容可通过以下命令在客户端中进行查看: geth --help 也可以访问github上的wiki文档查看,地址为: https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options 具体内容 NAME: geth - go-ethereum命令行接口 USAGE: geth [options] command [command options] [arguments...] VERSION: 1.4.11-s
程序新视界
2022/05/06
5020
go-kit 微服务 整合Promtheus解决监控告警问题
Prometheus基于中央化的规则计算、统一分析和告警的新模型, 完美地解决了传统监控模型的痛点。所以说其对传统监控系统的测试和告警模型进行了彻底的颠覆。
Johns
2021/04/08
1.4K0
go-kit 微服务 整合Promtheus解决监控告警问题
golang源码分析:mysql同步工具gravity(2)
在分析完gravity的原理和如何使用以后,我们开始分析下它的源码。gravity有5个入口,代表了5个工具。
golangLeetcode
2023/09/06
3950
golang源码分析:mysql同步工具gravity(2)
Bytom侧链Vapor源码浅析-节点出块过程
在这篇文章中,作者将从Vapor节点的创建开始,进而拓展讲解Vapor节点出块过程中所涉及的源码。
比原链Bytom
2020/08/07
6210
以太坊区块设计
区块链是由包含交易的区块按照时间先后顺序依次连接起来的数据结构,这种数据结构是一个形象的链表结构,所有数据有序地链接在同一条区块链上,每个区块通过一个hash指针指向前一个区块,hash指针其实是前一个区块头进行SHA256哈希计算得到的,通过这个哈希值,可以唯一的识别一个区块,然后将每个区块连接到其区块头中前一个区块哈希值代币的区块后面,从而构建出一条完整的区块链。
Al1ex
2023/05/26
2.2K0
以太坊区块设计
以太坊win平台和Linux 私链搭建,交易,添加多节点
先上一篇的以太坊的私有搭建,交易,节点连接,结合搭建的步骤对以太坊进行深入介绍。本文介绍的方式在win10 和ubuntu16.04 的方式测试过。 第一步:geth的安装,请直接移步:https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum 或者百度其他博客。为了方便操作,windows 平台在安装完成geth后 ,最好将geth.exe 所在的目录添加到Path环境变量中以便于开发。linux 的方式推荐使用ppa的方式安装。如果不是也推荐奖geth 添加到环境变量里面。 第二步:创建创世块 先不要想太多直接复制我的创世块用: 新建一个文件夹名为mynode,然后在mynode 文件夹里面创建一个文件
地球流浪猫
2018/08/02
6140
推荐阅读
相关推荐
多链支持,真没你想的那么简单
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验