halo~我是bay_Tong桐小白
本文内容是桐小白个人对所学知识进行的总结和分享,知识点会不定期进行编辑更新和完善,了解最近更新内容可参看更新日志,欢迎各位大神留言、指点
【微机原理与接口技术学习实践选择以x86架构系列机为研究学习对象,ARM架构原理类似可类比进行理解学习】
汇编语言程序设计初步——debug编写调试指令序列
-
- 汇编语言程序设计概述
- 指令在存储器内的组织存放结构
-
- 存储器的分段结构
- 8086/8088段寄存器与指令指针寄存器
- 8086/8088通用数据寄存器
- 8086/8088中16位地址向20位地址的变换
- DOS
- debug
- DOS中debug编写和调试指令序列
【更新日志】
最近更新:
- 更新内容——对汇编语言程序设计概述部分增加了一些易理解的先导解释(2021.6.19)
- 持续更新中……
汇编语言程序设计概述
计算机中有很多种语言,每次学习语言及语言处理相关的内容,我都习惯用这样一个被我在很多篇文章里都举烂了的例子来进行简单的解释:
打一个简单的比方
显然这是一个略悲伤的故事
因此人们需要想办法完成类似这样的任务
计算机中有很多种程序语言
- 汇编语言就可以说是将难以记忆的0/1码这样的机器语言进行第一次集成和记录,就是用一些简单的易懂的指令,比如用MOV来将对应的能完成移动、存储操作的一串0/1码进行标记,帮助人们记忆、理解
- 这些指令可以被叫做助记符,即帮助人们记忆的符号,用这些符号写成的语句所组成的集合就成了一种计算机语言,即汇编语言
- 而一句汇编语句完成的功能往往很单一,而且对于不了解计算机结构、工作原理的人来说,编写和理解汇编语言是很困难的,平时被人们所熟知的C、C++、Java、python等高级语言则是又一次集成和处理,它更接近人类的表达习惯,编写起来不需要理解很多计算机处理问题时的细节,进行应用开发等工作使用起来会更加方便
- 但是要深入考虑、研究计算机工作的每一个环节,检查、编写或者优化计算机工作工程中的机制、逻辑、细节,高级语言往往是做不到的,就必须要学习汇编语言
【具体其它计算机语言方面的知识要点详细见专业基础专栏文章《计算机语言处理相关知识要点区分汇总》】
汇编语言: 是一种用符号表示的,面向CPU指令系统的程序设计语言
汇编语言特点:
- 对机器的依赖性很大,每种机器都有它专用的汇编语言,用户须对机器的硬件及软件资源有足够的了解才能设计汇编语言程序
- 汇编语言指令是“符号化”的机器指令,每一条汇编语言的指令与机器语言指令都是一一对应的,学习汇编语言可以从根本上了解、理解计算机的工作过程
- 在计算机系统中,机器自检、系统初始化、输入输出驱动程序等功能仍是由汇编语言程序来实现
- 汇编语言编写的程序目标代码占用的内存少,执行速度快,效率高,实时性强,在需要节省内存空间和提高程序运行速度等情况下(如实时通信、实时控制等)常采用汇编语言编写程序
- 汇编语言可以直接调用操作系统设置的中断处理程序,方便用户对微机系统资源的利用
源程序: 用汇编语言编写的程序为“源程序”,文件扩展名为“.asm”,即ASM文件,该文件为ASCII码文件
汇编: 用汇编语言编写的源程序在交付计算机执行之前,需要翻译成机器可直接识别和运行的二进制代码形式,这个翻译过程称为汇编
反汇编: 把目标代码转为汇编代码的过程,也可以说是把机器语言转换为汇编语言代码、低级转高级的意思
汇编程序: 执行和完成汇编任务的程序称为汇编程序。
- 常用的汇编程序为MASM.EXE,此程序可将ASCII码的源程序转换成二进制代码表示的目标文件,称为OBJ文件
- 在转换过程中,如果源程序中有语法错误,汇编程序将指出源程序中错误的位置和种类,提示用户修改源程序,直至无语法错误,才能生成OBJ文件
- OBJ文件仍然不能被CPU直接运行,需要经过连接程序LINK.EXE连接后才能形成可执行程序.EXE
(OBJ文件中某些指令的地址还未完全确定,另外可能需要将多个目标程序组合成一个功能更强的程序,或要和某些高级语言的目标程序进行连接,因此需要由连接程序连接后才能形成可执行程序)
汇编语言语句分类:
- 指令语句——即指令系统中各条指令,每条指令都对应着相应的机器语言目标代码,也即对应着CPU一种操作
- 伪指令语句——不产生机器语言目标代码,而是指示、引导汇编程序在汇编过程中做一些操作(如界定段的起始位置、为数据分配合适的存储单元等)。伪指令在汇编程序运行时执行,在汇编阶段全部完成,在目标程序中不存在伪指令语句
- 宏指令语句——用户按照一定的规则自己设计的指令,是若干指令的集合,即用一条宏指令语句代替若干条指令语句。使用宏指令语句的目的主要是为了简化源程序,在汇编程序汇编时还是将宏指令语句还原回指令语句的形式,转换成一条条机器目标代码形式(支持宏指令语句的汇编程序称为“宏汇编程序”,MASM.EXE就是宏汇编程序)
指令在存储器内的组织存放结构
8086 CPU的内部组成结构从功能上可分为两个独立的部分,即总线接口单元(BIU)与执行单元(EU)。总线接口单元(BIU)通常含有指令队列缓冲器、段寄存器、指针寄存器等;执行单元(EU)通常含有通用数据寄存器等
【CPU内部组成结构详细后续更新……】
存储器的分段结构
程序在内存中是分段存放的,即指令代码、数据、堆栈分开存放,每个段称为逻辑段(简称段),每段有明确的首地址,段和段之间的地址可以连续、断开、重叠
段的分类:
- 代码段:存放CPU可以运行的指令、程序代码
- 数据段:存放程序中定义的变量等数据
- 堆栈段:在程序调用时存放调用处的地址、寄存器的内容、调用的参数等,在调用完后对寄存器进行恢复,即存放一些临时保存的数据
- 附加数据段:与数据段配合使用,使编程更加灵活
每类段可以由多个逻辑段组成,每个逻辑段的长度不大于64KB(原因详见下文16位地址向20位地址变换部分)
8086/8088段寄存器与指令指针寄存器
8086/8088中段寄存器与指令指针寄存器通常在BIU单元中,8086/8088用20位地址寻址内部存储器,由两个16位寄存器配合形成20位地址进行寻址
8086/8088的4个段地址寄存器:
- 代码段寄存器(CS):存放代码段的段地址
- 数据段寄存器(DS):存放数据段的段地址
- 堆栈段寄存器(SS):存放堆栈段的段地址
- 附加段寄存器(ES):存放附加段的段地址
8086/8088的指令指针寄存器(IP): 指令指针寄存器IP(X86型CPU)相当于ARM型CPU中的程序计数器PC,用于控制程序中指令的执行顺序。IP中的值的主要变化发生在下列情况:
- 通常正常运行时,IP中含有BIU要取的下一条指令的偏移地址
- 一般情况下,每从内存中存取一次指令码,IP就自动加1修正,指向将要执行的下一条指令的偏移存储地址,从而保证指令的顺序执行
- 当程序中有转移、调用、中断等跳转指令时,IP中的地址将根据指令条件强迫改写实现跳转
- IP中的值不能被程序直接访问,即不能用指令取出或修改IP中的值
8086/8088通用数据寄存器
8086/8088中通用寄存器通常在EU单元中,EU中有8个16位的通用寄存器,分为两组,分别是数据寄存器以及指针和变址寄存器
数据寄存器: EU中有4个16位的数据寄存器 AX、BX、CX、DX,每个数据寄存器的高低字节均可以拆分成两个8位的数据寄存器独立使用,即
- AX:累加器
- BX:基址寄存器
- CX:计数寄存器
- DX:数据寄存器
指针和变址寄存器: EU中有4个16位的指针和变址寄存器SP、BP、SI、DI,通常用于存放内存储器的偏移地址,以便CPU去内存储器中存取操作数
- SP:堆栈指针,总是指向堆栈段的顶部
- BP:基数指针,通常存放堆栈段的偏移地址
- SI:源变址指针,和DI一般用于存放数据段的偏移地址或地址偏移量
- DI:目的变址指针,和SI一般用于存放数据段的偏移地址或地址偏移量
8086/8088中16位地址向20位地址的变换
两个16位寄存器分别存放段地址和偏移地址(通常段地址存储在段寄存器中,偏移地址保存在指针寄存器中),通过地址加法器完成以下变换:
此地址变换机制隐含两个注意点:
- 一个段内存空间的起始地址必然是16的倍数
- 一个段的最大空间为2^16B = 64KB
在运行程序时,当前指令所在的码段地址由CS给出,偏移地址由IP给出,通过BIU内的地址加法器形成20位物理地址去内尺寸寻址,同时IP自动加1修正,指向要执行的下一条指令的偏移地址
拓:当8086/8088CPU复位时,CS中的内容位FFFFH,IP的内容为0000H,所以计算机复位后的第一条指令是从FFFF0处开始运行的,这个地址通常都是存放在主板上ROM中的BIOS程序的起始地址,该程序运行开机自检及自举程序
DOS
磁盘操作系统(Disk Operating System),早期个人计算机上的一类操作系统。可以直接操纵管理硬盘的文件,以DOS的形式运行。微软图形界面操作系统Windows NT问世以来,DOS是一个后台程序的形式出现的,命名为Windows命令提示符,通过运行命令提示符程序 cmd.exe进入
debug
DOS提供的有力的侦错、跟踪程序运行、检查系统数据 的工具程序,在字符界面下以单字符命令方式工作,为汇编语言程序员提供了有效的调试手段。它的功能包括:
- 直接输入、更改、跟踪、运行汇编程序
- 观察操作系统的内容
- 查看ROM BIOS的内容
- 观察更改RAM内部的设置值
- 以扇区或文件的方式读写软盘数据
WindowsXP、Windows2003 Server自带debug.exe,其它更高版本Windows系列操作系统需要下载DOSBOX自行进行安装配置(详细操作后续更新)
DOS中debug编写和调试指令序列
【本学习实践选择了在WindowsXP操作系统虚拟机中进行完成】
【本学习实践为部分debug命令的练习执行,详细debug命令语义用法见 百度百科debug命令 命令功能部分】
- 启动DEBUG(开始菜单->cmd)
- “R”命令查看当前所有寄存器和标志位的状态
由“R”命令显示结果可知DEBUG初始工作环境:
DS = ES = SS = CS = 0AE7;
IP = 0100;SP = FFEE;BP = SI = DI = 0000;
NV(无溢出) UP(增量) EI(运行中的) PL(正号)
NZ(非零) NA(无辅助进位) PO(奇数) NC(无进位)
- “D”命令查看各地址所存数据
- “E”命令对指定地址内容进行修改,如使用“E”命令对0AE7:0110地址的内容修改为55并再次使用“D”命令查看修改结果
- “A”命令输入汇编源程序指令,输入两个回车或键入 ctrl + c 结束编辑
- 使用“U”命令进行反汇编
以汇编语言指令 MOV AX,1234 为例,“A”命令输入汇编指令,汇编生成对应机器码为B83412,“U”命令即进行反汇编,将机器码B83412转换为汇编语言指令 MOV AX,1234
- “T”命令单步执行汇编程序
- “G”命令设置断点执行程序
断点执行可以方便得查看某一段程序指令的运行结果,分析执行过程以便寻找程序是否存在逻辑错误,断点的选择应尽量选择放在循环、跳转等逻辑结构复杂的关键位置,以方便更好的进行分析,达到更好的调试效果
- 根据反汇编和程序运行过程IP的变化,详细分析指令地址、目标代码、程序指令、指令代码存放规律之间的关系。以第一条指令的反汇编结果
为例,对程序控制执行机理分析:
- 自编指令段,如:输入一个数(如4),完成从0到这个数的所有数的求和,计算结果存在寄存器AX中
指令设计:
1)AX寄存器存放临时计算结果与最终计算结果
2)CX寄存器存放循环变量
3)ADD指令实现算数加法运算
4)LOOP指令实现指令的跳转控制
汇编语言指令代码如下:
执行结果如下:
持续更新中……
我是桐小白,一个摸爬滚打的计算机小白