【汇编语言】[BX]和loop指令(二)——在Debug中跟踪用loop指令实现的循环程序

在这里插入图片描述

文章目录

  • 前言
  • 1. 题目引入
    • 1.1 问题一
    • 1.2 问题二
    • 1.3 问题三
    • 1.4 代码实现
  • 2. 程序跟踪
    • 2.1 加载程序,用r命令查看寄存器内容
    • 2.2 用U命令查看内存中的程序
    • 2.3 用T命令进行程序跟踪
    • 2.4 用P命令使得程序返回
  • 3. 循环次数更多的程序
    • 3.1 代码实现
    • 3.2 一个新的命令——g
    • 3.3 如何使用g命令
    • 3.4 循环次数太多了!!!
    • 3.5 P命令的又一个功能——一次执行完循环
    • 3.6 g命令也可以快速出循环
  • 结语

前言

📌

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

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

1. 题目引入

考虑这样一个问题,计算ffff:0006单元中的数乘以3,结果存储在dx中。

我们分析一下,可能会遇到以下三个问题:

1.1 问题一

(1)运算后的结果是否会超出dx所能存储的范围?

ffff:0006 单元中的数是一个字节型的数据,范围在0-255之间,则用它和3相乘结果不会大于65535,可以在dx中存放下。

1.2 问题二

(2)我们用循环累加来实现乘法,用哪个寄存器进行累加?

我们将ffff:0006单元中的数赋值给ax,用dx进行累加。先设(dx)=0,然后做3次(dx)=(dx)+(ax)。

1.3 问题三

(3) ffff:0006单元是一个字节单元,ax是一个16位寄存器,数据长度不一样,如何赋值?

注意,我们说的是“赋值”,就是说,让 ax 中的数据的值(数据的大小)和ffff:0006 单元中的数据的值(数据的大小)相等。

例如:8 位数据01H和16位数据0001H的数据长度不一样,但它们的值是相等的。

那么我们如何赋值?

设ffff:0006单元中的数据是XXH,若要ax中的值和ffff:0006单元中的相等,ax中的数据应为00XXH。所以,若实现ffff:0006单元向ax赋值,我们应该令(ah)=0,(al)=(ffff6H)。

1.4 代码实现

想清楚以上的3个问题之后,编写程序如下。

assume cs:code
code segmentmov ax,0ffffhmov ds axmov bx,6		;以上,设置ds:bx指向ffff:6mov al,[bx]mov ah,0		;以上,设置(al)=((ds*16)+(bx)),(ah)=0mov dx,0		;累加寄存器清0mov cx,3		;循环3次
s:	add dx,axloop s			 ;以上累加计算(ax)*3mov ax,4c00hint 21h			 ;程序返回code ends
end

注意程序中的第一条指令mov ax,0ffffh

我们知道大于9FFFH的十六进制数据A000H、A001H、…… 、C000H、C001H、……、FFFEH、FFFFH等,在书写的时候都是以字母开头的。而在汇编源程序中,数据不能以字母开头,所以要在前面加0。(因为我们使用的MASM编译器对于字母开头的数据不认识,会报错

2. 程序跟踪

下面我们对程序的执行过程进行跟踪。

首先 ,我们将它编辑为源程序文件,文件名定为 p3.asm ;对其进行编译连接后生成p3.exe;(这些知识在【汇编语言】第一个程序(三)—— 深度剖析汇编程序的执行流程:编辑、编译、连接与运行_汇编语言程序 运行这一章的内容中已经学习过了);然后再用Debug对p3.exe中的程序进行跟踪。

2.1 加载程序,用r命令查看寄存器内容

用Debug加载 p3.exe 后,用r命令查看寄存器中的内容,如下图所示。(不同的电脑呈现出来的初始内容可能不同

在这里插入图片描述

上图中(ds)=0B2DH,所以,程序在0B3D:0处。(这个我们在【汇编语言】第一个程序(四)—— 谁在幕后启动程序 : 探讨可执行文件的装载与执行这篇文章中讲过,是因为在程序加载到内存时会有一个程序段前缀psp在我们的程序的前面,而这个psp的大小为256个字节

2.2 用U命令查看内存中的程序

我们看一下,(cs)=0B3DH,(IP)=0,CS:IP 正指向程序的第一条指令。再用u命令看一下被 Debug 加载入内存的程序,如图下所示。

在这里插入图片描述

可以看到,从0B3D:0000-0B3D:001A是我们的程序,0B3D:0014处是源程序中的指令loops,只是此处loops中的标号s已经变为一个地址0012h。如果在执行“loop 0012”时,cx减1后不为0,“loop 0012”就把IP设置为0012h,从而使 CS:IP 指向0B3D:0012处的 add dx,ax,实现转跳

2.3 用T命令进行程序跟踪

我们开始进行跟踪,如下图所示。

在这里插入图片描述

上图中,前3条指令执行后,(ds)=fffh,(bx)=6,ds:bx指向 ffff:6单元。Debug 显示出当前要执行的指令“mov al,[bx]”,因为是读取内存的指令,所以 Debug 将要访问的内存单元中的内容也显示出来,可以看到屏幕最右边显示的“ds:0006=32”,由此,我们可以方便地知道目标单元(ffff6)中的内容是32h。

继续执行,如下图所示。

在这里插入图片描述

上图中,这两条指令执行后,(ax)=0032h,完成了从:6单元向ax的赋值

继续,如下图所示。

在这里插入图片描述

上图中,这两条指令执行后,(dx)=0,完成对累加寄存器的初始化;(cx)=3,完成对循环计数寄存器的初始化。

下面,将开始循环程序段的执行,继续,如下图所示。

在这里插入图片描述

上图中,CPU 执行0B3D:0012处的指令“add dx,ax”后,(IP)=0014h,CS:IP 指向0B3D:0014处的指令“loop 0012”。

CPU 执行“loop 0012”,

第一步先将(cx)减1,(cx)=2;

第二步因(cx)不等于0,将IP设为0012h。

指令“loop 0012”执行后,(IP)=0012h,CS:IP再次指向0B3D:0012处的指令“add dx,ax”,这条指令将再次得到执行。

❗注意,“loop 0012”执行后(cx)=2,也就是说,“loop 0012”还可以进行两次循环。

接着,将重复执行“add dx,ax”和“loop 0012”,直到(cx)=0为止,如下图所示。

在这里插入图片描述

注意上图中,最后一次执行“loop 0012”的结果。

执行前(cx)=1,CPU 执行“loop 0012”,

第一步,(cx)=(cx)-1,(cx)=0;

第二步,因为(cx)=0,所以 loop 指令不转跳,(IP)=0016h,CPU向下执行0B3D:0016处的指令“mov ax,4c00

在完成最后一次“add dx,ax”后,(dx)=96h,此时 dx中为累加计算(ax)*3的最后结果。

2.4 用P命令使得程序返回

我们继续,将程序执行完,如下图所示。

在这里插入图片描述

上图中,执行完最后两条指令后,程序返回到Debug中。注意“int21”要用p命令执行

3. 循环次数更多的程序

3.1 代码实现

上面,我们通过对一个循环程序的跟踪,更深入一步地讲解了loop指令实现循环的原理。下面,我们将之前的程序改一下,计算ffff:0006单元中的数乘以123,结果存储在dx 中。

这很容易完成,只要将循环的次数改为123就可以了。程序如下。

assume cs:code
code segmentmov ax,0ffffhmov ds axmov bx,6		;以上,设置ds:bx指向ffff:6mov al,[bx]mov ah,0		;以上,设置(al)=((ds*16)+(bx)),(ah)=0mov dx,0		;累加寄存器清0mov cx,123		;循环123次
s:	add dx,axloop s			 ;以上累加计算(ax)*3mov ax,4c00hint 21h			 ;程序返回code ends
end

3.2 一个新的命令——g

我们用 Debug对这个程序的循环程序段进行跟踪,现在有这样一个问题:前面的条指令,即标号s前的指令,已经确定在逻辑上完全正确,我们不想再一步步地跟踪了,只想跟踪循环的过程。所以希望可以一次执行完标号s前的指令。可以用一个新的(对我们来说是新的,因为以前没用过)Debug命令g来达到目的。

3.3 如何使用g命令

下面来实际操作一下,我们用刚才的程序生成最终的可执行文件“c:masm\p4.exe”,用Debug 加载 p4.exe,然后看一下程序在内存中的情况,如下图所示。

在这里插入图片描述

上图中,循环程序段从CS:0012开始,CS:0012前面的指令,我们不想再一步步地跟踪,希望能够一次执行完,然后从CS:0012处开始跟踪。可以这样来使用g命令,“g 0012”,它表示执行程序到当前代码段(段地址在CS中)的0012h处。

也就是说“g 0012”将使 Debug从当前的CS:IP指向的指令执行,一直到(IP)=0012h为止。具体的情况如下图所示。
在这里插入图片描述

上图中,Debug执行“g 0012”后,CS:0012前的程序段被执行,从各个相关的寄存器中的值,我们可以看出执行的结果。

3.4 循环次数太多了!!!

下面我们对循环的过程进行跟踪,如下图所示。

在这里插入图片描述

上图中,我们跟踪了两次循环的过程。其实,通过这两次循环过程,已经可以确定循环程序段在逻辑上是正确的。

我们不想再继续一步步地观察循环的过程了,怎样让程序向下执行呢?继续像从前那样使用t命令?

显然这是不可行的,因为还要进行121((cx)=79h)次循环,如果像前两次那样使用t命令,我们得使用121*2=242次t命令才能从循环中出来。

3.5 P命令的又一个功能——一次执行完循环

这里的问题是,我们希望将循环一次执行完。可以使用p命令来达到目的。再次遇到loop 指令时,使用p命令来执行,Debug 就会自动重复执行循环中的指令,直到(cx)=0为止。具体情况如下图所示。

在这里插入图片描述

上图中,在遇到“loop 0012”时,用p命令执行,Debug 自动重复执行“loop 0012”和“add dx,ax”两条指令,直到(cx)=0。最后一次执行“loop 0012”后,(cx)=0,(IP)=0016h,当前指令为CS:0016 处的“mov ax,4c00”。

3.6 g命令也可以快速出循环

当然,也可以用g命令来达到目的,可以用“g 0016”直接执行到CS:0016处。具体情况如下图所示。

在这里插入图片描述

结语

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

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

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

在这里插入图片描述

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

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

相关文章

Unity照片墙效果

Unity照片墙效果,如下效果展示 。 工程源码

鸿蒙HarmonyOS开发生日选择弹框

鸿蒙HarmonyOS开发生日选择弹框 生日选择弹框和城市选择弹框差不多,都是通过观察上一个数据变化来设置自己的数据 一、思路: 一个弹框上建三个compoent,一个年,一个月,一个日。日的数据是根据年和月进行变化的 二、…

浏览器内核版本更新:Chrome 130✔

SunBrowser 内核版本更新至 Chrome 130,UA 同步更新至 130。 如何更新浏览器内核版本? 本地设置更新 在 AdsPower 客户端点击右上角的[设置],再点击[本地设置],下滑找到版本信息,选中需要的内核版本立即下载。 新建浏…

【实践】某央企研究院如何打造IT监控告警平台?

01客户简介: 案例客户为某央企下属研究院。 02痛点分析: 随着信创国产化持续推进,案例客户已完成部分IT核心系统的替代,部署了一系列国产软硬件设施,如Kylinv10操作系统、融智通网络设备等。由于信创生态不够成熟&a…

SpringBoot在线教育系统:集成第三方服务

5系统详细实现 5.1 普通管理员管理 管理员可以对普通管理员账号信息进行添加修改删除操作。具体界面的展示如图5.1所示。 图5.1 普通管理员管理界面 5.2 课程管理员管理 管理员可以对课程管理员进行添加修改删除操作。具体界面如图5.2所示。 图5.2 课程管理员管理界面 5.3 …

vscode | 开发神器vscode快捷键删除和恢复

目录 快捷键不好使了删除快捷键恢复删除的快捷键 在vscode使用的过程中,随着我们自身需求的不断变化,安装的插件将会持续增长,那么随之而来的就会带来一个问题:插件的快捷键重复。快捷键重复导致的问题就是快捷键不好使了&#xf…

C++优选算法九 链表

一、常用技巧 画图!直观形象,便于理解。引入虚拟“头”结点。不吝啬空间。快慢双指针: 判环 找链表中环的入口 找链表中倒数第n个结点 二、常用操作 创建一个新结点尾插头插 三、示例题目 1.两数相加. - 力扣&#xff08…

计算机网络:网络层 —— 虚拟专用网 VPN

文章目录 虚拟专用网 VPN 概述内联网 VPN外联网 VPN 虚拟专用网 VPN 概述 虚拟专用网(Virtual Private Network,VPN):利用公用的因特网作为本机构各专用网之间的通信载体,这样形成的网络又称为虚拟专用网。 出于安全…

Web 安全基础知识梳理大全,零基础入门到精通,收藏这篇就够了

一、各种linux虚拟机忘记密码 1、红帽忘记密码修改root密码 1 在重启的时候 e 进入 2 在linux16 后面找到UTF-8 在后面加 rd.break 然后ctrlx 3 这时候可以输入mount 看一下 会发现根为 /sysroot/ 没有w权限,只有ro权限 4 输入 mount -o remount,r…

非凸科技助力第49届ICPC亚洲区域赛(成都)成功举办

10月26日-27日,由电子科技大学承办、非凸科技与华为共同支持的第49届ICPC国际大学生程序设计竞赛亚洲区域赛(成都)在郫都区体育中心体育馆顺利举行。非凸科技期待与产学研各界专家、青年才俊一起,推动基础科学理论研究的重大突破&…

ssm051网上医院预约挂号系统+jsp(论文+源码)_kaic

本科毕业设计论文 题目:网上医院预约挂号系统设计与实现 系 别: XX系(全称) 专 业: 软件工程 班 级: 软件工程15201 学生姓名: 学生学号: 指导教师&#xff1a…

EtherCAT转ModbusTCP相关技术

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 MS-GW15 概述 MS-GW15 是 EtherCAT 和 Modbus TCP 协议转换网关,为用户提供一种 PLC 扩展的集成解决方案,可以轻松容易将 Modbu…

qt QTextStream详解

1、概述 QTextStream类是Qt框架中用于处理文本输入输出的类。它提供了一种方便的方式,可以从各种QIODevice(如QFile、QBuffer、QTcpSocket等)中读取文本数据,或者将文本数据写入这些设备中。QTextStream能够自动处理字符编码的转…

大数据-201 数据挖掘 机器学习理论 - 决策树 局部最优 剪枝 分裂 二叉分裂

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

项目_Linux_网络编程_私人云盘

概述 项目功能总述: 该项目使用TCP进行通信,实现文件的上传和下载。云盘的文件同步有手动同步、实时同步、定时同步这三种。本项目主要实现的是手动同步的功能,重点训练在如何使用TCP进行文件传输。 选择TCP的原因: 文件的传输…

细腻的链接:C++ list 之美的解读

细腻的链接:C list 之美的解读 前言: 小编在前几日刚写过关于vector容器的内容,现在小编list容器也学了一大部分了,小编先提前说一下学这部分的感悟,这个部分是我学C以来第一次感到有难度的地方,特别是在…

Java之包,抽象类,接口

目录 包 导入包 静态导入 将类放入包 常见的系统包 抽象类 语法规则 注意事项: 抽象类的作用 接口 实现多个接口 接口间的继承 接口使用实例 (法一)实现Comparable接口的compareTo()方法 (法二)实现Comp…

qt QDragEnterEvent详解

1、概述 QDragEnterEvent是Qt框架中用于处理拖放进入事件的一个类。当用户将一个拖拽对象(如文件、文本或其他数据)拖动到支持拖放操作的窗口部件(widget)上时,系统会触发QDragEnterEvent事件。这个类允许开发者在拖拽…

永恒之蓝漏洞复现

永恒之蓝漏洞复现 1 实验准备 1台靶机 win7 关闭防火墙 控制面板->系统和安全->Windows 防火墙 192.168.184.131 1台攻击者 kali 192.168.184.129 2 实施攻击 kali操作 1.输入msfconsole回车 2.搜索ms17_010模块 msf6 > search ms17_010 3.选择编号为3的模块 use 3…

c++拷贝构造函数

1.拷贝构造函数 拷贝构造函数的调用时机 class A { public://默认构造函数A(){m_Hp 100;cout << "A默认构造函数调用完毕" << endl;}//有参构造函数A(int hp){m_Hp hp;cout << "A有参构造函数调用完毕" << endl;}A(const A&…