当前位置: 首页 > news >正文

masm汇编器以及汇编流程

用汇编语言编写的源程序不能直接在其目标计算机上执行,必须通过翻译或汇编将其转换为可执行代码。实际上,汇编器与编译器 (compiler) 很相似,编译器是一类程序,用于将 C++ 或 Java 程序翻译为可执行代码。

汇编器生成包含机器语言的文件,称为目标文件 (object file)。这个文件还没有准备好执行,它还需传递给一个被称为链接器 (linker) 的程序,从而生成可执行文件 (executable file)。这个文件就准备好在操作系统命令提示符下执行。

汇编-链接-执行周期

下图总结了编辑、汇编、链接和执行汇编语言程序的过程。下面详细说明每一个步骤。
 

汇编-链接-执行周期
 

  • 步骤1:编程者用文本编辑器 (text editor) 创建一个 ASCII 文本文件,称之为源文件。
  • 步骤2:汇编器读取源文件,并生成目标文件,即对程序的机器语言翻译。或者,它也会生成列表文件。只要出现任何错误,编程者就必须返回步骤 1,修改程序。
  • 步骤3:链接器读取并检查目标文件,以便发现该程序是否包含了任何对链接库中过程的调用。链接器从链接库中复制任何被请求的过程,将它们与目标文件组合,以生成可执行文件。
  • 步骤4:操作系统加载程序将可执行文件读入内存,并使 CPU 分支到该程序起始地址,然后程序开始执行。

列表文件

列表文件 (listing file) 包括了程序源文件的副本,再加上行号、每条指令的数字地址、每条指令的机器代码字节(十六进制)以及符号表。符号表中包含了程序中所有标识符的名称、段和相关信息。
高级程序员有时会利用列表文件来获得程序的详细信息。下面的代码展示了 AddTwo 程序的部分列表文件,现在进一步查看这个文件。1〜7 行没有可执行代码,因此它们原封不动地从源文件中直接复制过来。第 9 行表示代码段开始的地址为 0000 0000(在 32 位程序中,地址显示为 8 个十六进制数字)。这个地址是相对于程序内存占用起点而言 的,但是,当程序加载到内存中时,这个地址就会转换为绝对内存地址。此时,该程序就会从这个地址开始,比如 0004 0000h。

; AddTwo.asm - adds two 32-bit integers.
; Chapter 3 example

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExitCode:DWORD

00000000 .code
00000000 main PROC
00000000 B8 00000005 mov eax, 5
00000005 83 C0 06 add eax,6

invoke ExitProcess,0
00000008 6A 00 push +000000000h
0000000A E8 00000000 E call ExitProcess
0000000F main ENDP
END main

第 10 行和第 11 行也显示了相同的开始地址 0000 0000,原因是:第一条可执行语句是 MOV 指令,它在第 11 行。请注意第 11 行中,在地址和源代码之间出现了几个十六进制字节,这些字节(B8 0000 0005)代表的是机器代码指令(B8 ),而该指令分配给 EAX 的就是 32 位常数值(0000 0005):

00000000 B8 00000005 mov eax, 5

数值 B8 也被称为操作代码(或简称为操作码),因为它表示了特定的机器指令,将一个 32 位整数送入 eax 寄存器。

第 12 行也是一条可执行指令,起始偏移量为 0000 0005。这个偏移量是指从程序起始地址开始 5 个字节的距离。(因为前面的mov eax占了1个字节,00000005占了4个字节)

第 14 行有 invoke 伪指令。注意第 15 行和 16 行是如何插入到这段代码中的,插入代码的原因是,INVOKE 伪指令使得汇编器生成 PUSH 和 CALL 语句,它们就显示在第 15 行和 16 行。

代码中展示的示例列表文件说明了机器指令是怎样以整数值序列的形式加载到内存的,在这里用十六进制表示:B8、0000 0005、83、C0、06、6A、00、EB、0000 0000。每个数中包含的数字个数暗示了位的个数:2 个数字就是 8 位,4 个数字就是 16 位,8 个数字就是 32 位,以此类推。所以,本例机器指令长正好是 15 个字节(2 个 4 字节值和 7 个 1 字节值)。

当程序员想要确认汇编器是否按照自己的程序生成了正确的机器代码字节时,列表文件就是最好的资源。如果是刚开始学习机器代码指令是如何生成的,列表文件也是一个很好的教学工具。

若想告诉 Visual Studio 生成列表文件,则在打开项目时按下述步骤操作:在 Project 菜单中选择 Properties,在 Configuration Properties 下,选择 Microsoft Macro Assemblero 然后选择 Listing File。在对话框中,设置 Generate Preprocessed Source Listing 为 Yes,设置 List All Available Information 为 Yes。同时设置list文件名。如图所示:

相关文章:

  • 汇编语言JMP和LOOP(转移)指令
  • 汇编相关运算符和指令
  • PN结
  • 汇编语言过程
  • JS中innerHTML、outerHTML、innerText 、outerText、value的区别与联系?jQuery中的text()、html()和val() ?
  • 操作系统相关
  • 编译和链接
  • 目标文件里有什么?
  • JS setTimeout和setInterval的区别
  • JavaScript 变量提升
  • JavaScript 调试
  • JavaScript 库(框架)
  • Cefsharp js调用c#与c#调用js
  • JavaScript之Window 对象
  • javascript之Navigator 对象
  • 【css3】浏览器内核及其兼容性
  • 【知识碎片】第三方登录弹窗效果
  • 4. 路由到控制器 - Laravel从零开始教程
  • 5、React组件事件详解
  • flask接收请求并推入栈
  • js写一个简单的选项卡
  • Linux gpio口使用方法
  • Spring Cloud中负载均衡器概览
  • 彻底搞懂浏览器Event-loop
  • 浮动相关
  • 浮现式设计
  • 排序(1):冒泡排序
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 栈实现走出迷宫(C++)
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • MPAndroidChart 教程:Y轴 YAxis
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • (12)Linux 常见的三种进程状态
  • (2)STL算法之元素计数
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (pojstep1.1.2)2654(直叙式模拟)
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (黑马C++)L06 重载与继承
  • (三)Honghu Cloud云架构一定时调度平台
  • (四)c52学习之旅-流水LED灯
  • (四)汇编语言——简单程序
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Core 通过 Ef Core 操作 Mysql
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • [ffmpeg] x264 配置参数解析
  • [Flutter]WindowsPlatform上运行遇到的问题总结
  • [HEOI2013]ALO
  • [IE编程] IE中对网页进行截图的编程接口
  • [nginx] LEMP 架构随笔
  • [NOI2020统一省选 A] 组合数问题 (推式子)