【微机原理与接口技术学习实践】汇编语言程序设计实现——.ASM文件、.OBJ文件、.EXE文件综合

halo~我是bay_Tong桐小白
本文内容是桐小白个人对所学知识进行的总结和分享,知识点会不定期进行编辑更新和完善,了解最近更新内容可参看更新日志,欢迎各位大神留言、指点

微机原理与接口技术学习实践选择以x86架构系列机为研究学习对象,ARM架构原理类似可类比进行理解学习


【更新日志】

最近更新:

  • 更新内容——新增循环实现1~10的加法汇编程序(2020.12.14)
  • 持续更新中……

汇编基本知识概念回顾

源程序: 用汇编语言编写的程序为“源程序”,文件扩展名为“.asm”,即ASM文件,该文件为ASCII码文件

目标程序: 二进制代码文件,文件扩展名为“.obj”

可执行程序: 能被CPU直接运行的程序,文件扩展名为“.exe”

汇编: 用汇编语言编写的源程序在交付计算机执行之前,需要翻译成机器可直接识别和运行的二进制代码形式,这个翻译过程称为汇编

反汇编: 把目标代码转为汇编代码的过程,也可以说是把机器语言转换为汇编语言代码、低级转高级的意思

汇编程序: 执行和完成汇编任务的程序称为汇编程序

扫描二维码关注公众号,回复: 12568643 查看本文章

MASM.EXE: 常见的汇编程序。将ASCII码的源程序转换成二进制代码表示的目标文件

LINK.EXE: 将目标文件二进制代码进行连接形成可执行程序
在这里插入图片描述
汇编语言语句分类:

  • 指令语句——即指令系统中各条指令,每条指令都对应着相应的机器语言目标代码,也即对应着CPU一种操作
  • 伪指令语句——不产生机器语言目标代码,而是指示、引导汇编程序在汇编过程中做一些操作(如界定段的起始位置、为数据分配合适的存储单元等)。伪指令在汇编程序运行时执行,在汇编阶段全部完成,在目标程序中不存在伪指令语句
  • 宏指令语句——用户按照一定的规则自己设计的指令,是若干指令的集合,即用一条宏指令语句代替若干条指令语句。使用宏指令语句的目的主要是为了简化源程序,在汇编程序汇编时还是将宏指令语句还原回指令语句的形式,转换成一条条机器目标代码形式(支持宏指令语句的汇编程序称为“宏汇编程序”,MASM.EXE就是宏汇编程序)

详细基本知识概念见本栏文章《汇编语言程序设计初步——debug编写调试指令序列》

DOS系统功能调用概述

DOS: 磁盘操作系统,可以直接操纵管理磁盘的文件

MS-DOS: 微软提供的磁盘操作系统,MS-DOS是个人电脑中最普遍使用的磁盘操作系统之一

PC-DOS: 是第一个被广泛安装使用的作业系统,由IBM为个人电脑专门开发的操作系统,和微软的MS-DOS几乎完全一样

【PS:可以认为MS-DOS和PC-DOS没有大的区别,出品单位不一样,虽然在功能上PC-DOS不见得逊于MS-DOS,但由于微软在世界软件业的垄断性优势,MS-DOS成为个人电脑中最普遍使用的磁盘操作系统之一】

DOS系统组成

  • 引导程序(BOOT):由格式化程序直接写入磁盘初始扇区
  • 输入输出管理系统(PC-DOS为IBMBIO.COM,MS-DOS为IO.SYS)
  • 文件管理和系统功能调用程序(PC-DOS为IBMDOS.COM,MS-DOS为MSDOS.SYS)
  • 命令处理程序(COMMAND.COM)
  • 各种外部命令:完成各种辅助功能的可执行文件

在DOS系统中有两层内部子程序可供用户调用,即与硬件相关的基本输入输出子程序ROM BIOS和与硬件无关的DOS层功能模块(系统功能调用程序)

这些程序是DOS操作系统的一部分,随着DOS系统驻留内存,使用汇编程序可直接调用这些子程序。这些完成不同功能的子程序是以中断服务程序的方式提供的,即其入口地址放置在中断向量表中,占用不同的中断类型号,用户在程序中以发送软中断命令的方式调用这些功能

【详细后续更新……】

汇编语言程序结构

源程序的结构

8086/8088汇编语言源程序采用分段结构,一个完整的源程序可以包含多个逻辑段(如数据段、堆栈段、代码段等)

(分段结构详细见本栏文章《汇编语言程序设计初步——debug编写调试指令序列》

段定义伪指令

汇编语言程序按段来组织程序、使用存储器。段定义伪指令即在汇编语言程序中定义逻辑段,指明段的名称、范围、属性等相关信息。完整的逻辑段的定义如下:

段名 SEGMENT <定位类型> <组合类型> <类别>
	...
	段体
	...
段名 ENDS
  • SEGMENT表示逻辑段的开始,ENDS表示逻辑段的结束,两者必须成对出现,且段名一致
  • 段名:用户为逻辑段所起的名字,须为符合汇编语言规则的合法标识符(汇编语言标识符规则详细见百度百科
  • 定位类型:表示所定义的段存放在内存空间时段起始边界地址对内存空间的要求,有四种定位类型情况:
    在这里插入图片描述
  • 组合类型:用来指示段和段之间是怎样连接和定位的。连接程序为了提高内存的使用效率,可以把不同模块中的同名段以指定的方式组合起来,组合的方法有六种:
    在这里插入图片描述
  • 类别:用单引号括起来的字符串。连接程序把类别相同的段放在连续的存储区中(可以不同名),类别名由用户选定,但一般为“CODE”、“STACK”、“DATA”等,表明该段的类型

段寻址伪指令ASSUME

段寻址伪指令是说明将哪个逻辑段的段起始地址装入段寄存器,即将哪个逻辑段设置为当前段。其格式如下:

ASSUME 段寄存器名:段名 <,……,段寄存器名:段名>
  • 段寄存器名是CS、DS、ES、SS中的一个,段名是用SEGMENT/ENDS伪指令语句定义的段名
  • ASSUME伪指令只能使汇编程序知道程序中段名和段寄存器的对应关系,指定了某逻辑段应通过哪一个段寄存器去寻址,但ASSUME伪指令并不会给段寄存器赋值,欲将段基址装入相应的段寄存器,必须通过指令实现
    在这里插入图片描述

过程定义伪指令PROC/ENDP

在汇编语言程序设计中,常常把具有一定功能的程序段设计成一个过程,也称子程序,可以将一些常用的操作或计算定义为过程,供主程序(主过程)调用,这样可以避免重复编程,同时使程序结构清晰,便于阅读、修改。过程定义伪指令格式如下:

过程名 PROC <类型>
	...
	过程体语句
	...
	RET
过程名 ENDP
  • 过程名:用户为过程所起的名字,必须是合法的标识符
  • 过程的开始(PROC)和结束(ENDP)应使用同一个过程名,同时,过程名也是过程入口的符号地址
  • 过程类型有两种:NEAR和FAR。NEAR型过程仅供段内调用,是过程的默认值;FAR型过程可供段间调用
  • 一个过程中至少要有一条过程返回指令RET,RET指令可以在过程的任何位置,但一个过程执行的最后一条指令一定是RET指令

汇编结束伪指令END

任何一个汇编源程序都必须用结束伪指令END作为源程序的最后一条语句。其格式为:

END 地址表达式
  • 地址表达式通常是一个已定义的语句标号,表示程序执行时的启动地址

一个完整的汇编语言源程序的结构如下:

DAT SEGMENT					;数据段开始
	X DB 6					;定义数据变量X和Y
	Y DB 8;
DAT ENDS					;数据段结束
STA SEGMENT STACK 'STACK'	;堆栈段开始,其中组合类型STACK一定要有
	DB 100 DUP(?)			;定义堆栈段大小为100个字节
STA ENDS					;堆栈段结束
CODE1 SEGMENT				;代码段开始
	ASSUME	CS:CODE1,DS:DAT,SS:STACK;段寻址
BEGIN PROC FAR				;BEGIN主过程开始
	  PUSH DS				;将PSP首址压栈,以便程序执行完后返回DOS
	  XOR AX,AX
	  PUSH AX
	  MOV AX,DAT			;将数据段的首址赋给数据段寄存器DS
	  MOV DS,AX
	  ...					;具体程序
	  RET					;BEGIN过程结束前的最后一条指令,程序运行INT 20H返回DOS
BEGIN ENDP					;BEGIN过程结束
CODE1 ENDS					;代码段结束
END BEGIN					;源程序结束BEGIN是程序第一条指令的地址

可执行文件的结构

汇编语言源程序经过汇编与连接后通常生成EXE结构的可执行程序(EXE文件),由操作系统装入内存后才能运行

EXE程序在内存的具体结构如下:
在这里插入图片描述
EXE程序由文件头和程序本身的二进制代码两部分组成。文件头也称程序段前缀(PSP),占用256个字节,其中的信息是DOS装载可执行文件时自动生成的。DOS通过PSP向用户传递参数,为用户程序提供程序正常结束和异常结束时返回DOS的途径

.ASM文件、.OBJ文件、.EXE文件的实现

为方便实践,选用Windows XP操作系统虚拟机环境里进行实践

使用工具:notepad++.exe、cmd.exe、masm.exe、link.exe、debug.exe

简单加法汇编程序

eg:实现一个加法汇编源程序5+3,并完成编译生成可执行文件

实践过程:

  • 使用notepad++进行汇编源程序的编写
    在这里插入图片描述
  • 将汇编程序masm.exe、连接程序link.exe与刚刚写好的源程序new.exe放在同一文件目录下
  • 打开cmd.exe,通过DOS命令使用汇编程序masm.exe对刚刚写好的源程序new.asm进行汇编,生成目标程序new.obj文件(若需重命名目标文件则在第一行输入要进行的命名,不需要按回车即可,对于后两个文件,.LST为汇编列表文件,.CRF为交叉引用文件,若不需要产生此两个文件同样按回车即可)
    在这里插入图片描述
  • 使用link.exe对刚刚生成的目标文件new.obj进行连接,生成可执行程序new.exe文件(若需重命名可执行文件则在第一行输入要进行的命名,不需要按回车即可,对于后两个文件,.MAP为地址分配文件,.LIB为库文件,若不需要产生此两个文件同样按回车即可)
    在这里插入图片描述
  • 如此即在当前目录下生成了可执行文件new.exe,该文件可以直接在命令行环境中运行

循环实现1~10的加法汇编程序

eg:在数据段从TABLE开始定义10个无符号的数1~10,每个数据为一个字节,计算这10个数的和,结果放到SUM字单元之中,并用debug进行调试

  • 启动notepad++软件,根据题目要求,进行汇编源程序的编写保存为sum.asm
    在这里插入图片描述

  • 用MASM.exe对sum.asm进行汇编,打开cmd窗口,进入MASM.exe的文件目录下(MASM.exe与LINK.exe、sum.asm文件应保存在同一文件目录下)
    在这里插入图片描述
    在这里插入图片描述

  • 输入指令用MASM.exe对sum.asm进行汇编,生成目标文件sum.obj
    在这里插入图片描述

  • 输入指令用LINK.exe对目标文件进行连接,生成可执行程序sum.exe
    在这里插入图片描述

  • 用debug对sum.exe进行调试,单步运行,观察运行过程是否正确
    在这里插入图片描述

  • 运行结束后,用debug的d命令查看SUM字单元结果,验证程序是否正确运行
    在这里插入图片描述
    可观察到SUM字单元结果为37H,即十进数55,结果正确

  • 用debug的e命令将TABLE中第3个无符号数改为0
    在这里插入图片描述
    用g重新运行程序至DOS返回中断指令之前(即在MOV AH, 4CH设置断点,可先用U命令进行反汇编查看汇编指令地址)
    在这里插入图片描述
    然后用d命令查看SUM字单元的结果,观察有什么变化,并验证结果是否正确
    在这里插入图片描述
    可观察到SUM字单元结果变为了34H,即十进制数52,结果正确

持续更新中……
我是桐小白,一个摸爬滚打的计算机小白

猜你喜欢

转载自blog.csdn.net/bay_Tong/article/details/110087580