汇编语言学习手把手的Debug教程

目录
  • Debug 是什么
  • Debug 实战
    • Debug -r
    • Debug -d
    • Debug -e
    • Debug -u
    • Debug -t
    • Debug -a
  • 总结

关于汇编的第一篇文章:
爱了爱了,这篇寄存器讲的有点意思

Hello大家好,我是程序员cxuan!我们上篇文章了解了一下基本的寄存器,这篇文章我们来进行实际操作一下。

原文链接:https://mp.weixin.qq.com/s/PQzuKtSiHwZleTosvop68A

我们以后将会用到很多 Debug 命令,这里我们先来熟悉一下它们。

Debug 是什么

Debug 是 Windows / Dos 操作系统提供的一种功能。使用 Debug 能让我们方便查看 CPU 各种寄存器的值、内存情况,方便我们调试指令、跟踪程序的运行过程。

接下来我们会用到很多 debug 命令,但是使用这些命令的前提是,你需要在电脑上安装一下 debug,Windows/Mac 都可以安装,获取链接我已经给你找出来了。阿,忘记说了,我们这里使用的是 Dos box来模拟汇编的操作环境。

传送门(Mac 和 Windows 都是):https://www.dosbox.com/download.php?main=1

下载完成后打开 DosBox ,打开之后是这样的。

此时我们输入 debug 命令应该提示的是

因为我们还没有进行连接和挂载,此时我们执行

mount c D:\debug

执行这条命令时,你需要现在 D 盘下创建一个 debug 文件夹,然后我们挂载到 debug 下面。

并且执行 C: 切换到 C 盘路径下。

此时我们就可以执行 debug 命令了。

这里需要注意一点,我在 Windows 10 系统下搭建 Debug 环境时,在挂载完成后输入 debug ,还是提示 Illegal command:debug ,此时你需要再下载一个 debug.exe ,贴心的我也把下载地址给你了。

下载地址:https://www.jb51.net/softs/467705.html 

需要下载里面的 debug.exe,然后把它放在你挂载的路径下,这里我挂载的路径时 D 盘下的 debug 文件夹。

放置完成之后,再输入 debug 就可以了。

因为每次打开 Dosbox 都会执行上面这些命令,真的好烦,那怎么办呢?一个简单的办法是在 Dosbox 安装路径下找到

打开之后,在末尾键入

就 OK 了,下次直接打开 Dosbox ,会默认执行这三条命令,至此,就是我搭建 Dosbox 遇到的所有问题了。

Debug 实战

玩儿汇编得学会用 Debug ,Debug 是一种调试程序,通过 Debug 能让我们能够看到内存值,跟踪堆栈情况,看到寄存器所暂存的内容等,同时也能够更好地帮助我们理解汇编代码,所以学会 Debug ,非常重要,这是一种不可或缺的动手能力。

下面我们会用到几种 Debug 命令,这里先简单介绍下。

Debug 命令有很多,不过常用的一般就上面这几个。

好了,现在我们直接进入正题,开始在 Dosbox 上正式进行 Debug 操作,首先打开 Dosbox。

嗯。。。。。。这个界面我们打开很多次了。

那我写个命令呢? 好吧,没演示过,下面就来了!

Debug -r

亲,用 Debug -r 就可以查看和修改 CPU 寄存器内容了呢。

查看寄存器内容。

这里需要注意一下 -r 大小写的问题,Debug -r 是查看寄存器内容。而 -R 则是无效指令。

上图列出来了很多寄存器,你可能觉得无从下手,不要乱,我们先从最基本的开始入手,也就是 CS 和 IP,CS(Code Segment)是代码段寄存器,一般也被称为段基址,可以认为是程序访问的入口,CPU 需要从 CS 中找到从哪个位置开始取指执行,但是我们还不知道要取哪一段,这时候 IP 的作用就体现出来了,IP(Instruction Pointer)就是指令指针寄存器,也叫做偏移地址,它会告诉我们从段基址开始,取哪一段的地址。

可以使用段基址:偏移地址来确定内存中的指定地址。

这里我们只是简单聊一下这两个寄存器的概念,要了解这两个寄存器的具体作用,可以看笔者之前的文章

传送门:汇编语言入门汇编指令及寄存器详解教程

使用 -r 也能够修改寄存器的内容,如下所示

-r 一般的格式是 -r 寄存器,然后系统会进行冒号提示,后面就是你要修改的内容。

Debug -d

使用 -d 指令可以查看内存中的内容。

输出的内存值默认是按照 CS:IP 的地址开始的,由于 CS 的值默认是 073F,而 IP 默认是 0100,所以 -d 的内存值是 073F:0100 。

-d 的格式很多,下面只介绍一下常用的几种格式。

形似 -d 1000:0 这种 -d 段基址 偏移地址的格式可以产生如下输出。

如上图所示,Debug 会列出指定内存单元中的的内容。上图中的每一个 00 都表示 8 位,如果是 4A,那么这八位展开来说就是 0010 1011 。每一行有 16 个 8 位,所以构成了 128 位内存地址。

为什么都是 00 呢,因为内存单元的值没有被改写,说白了就是这块内存区域没有存值,如何改写我们后面回收。

每一行的中间都有一个 -,这个是为了便于我们阅读来设置的,- 号前后都有 8 个内存单元,这样便于查看。

右侧几个 … 表示每个内存单元可显示的 ASCII 码字符,因为内存没有值,所以也没有对应的 ASCII 码。我们可以数一下,每行有 16 个 . ,这表示每一个 00 都对应了一个 ASCII 码。

我们可以使用 -d 1000:9 这种 -d 段基址:起始偏移地址 格式来显示从 1000 的第几位开始。

Debug 从 1000:9 开始,一直到 1000:88,一共是 128 个字节,第一行中的 1000:0 ~ 1000:8 中的内容没有显示。

还可以使用 -d 1000:0 9 这种 -d 段基址:起始偏移地址 结尾偏移地址的格式来输出。

还可以是使用 -d 偏移地址来在不指定段基址的情况下,查看内存值。

Debug -e

上面说的都是查看内存中指定位置或者区域的值,下面我们要来改写一下内存值。

使用 -e 可以改写内存值,比如我们想要改写 1000:0 ~ 1000:f 中的内容,可以使用 -e 1000:0 0 1 2 3 4 5 6 7 8 9 0 a b c d e f 这种方式,如下图所示。

这里需要注意下,在进行 -e 改写的时候,每个值中间都有一个空格,如果没有空格的话,会当做一个内存值来看待。

然后用 -d 1000:0 看到我们刚改写的内存值。

还可以使用提问的方式来逐个修改从某一地址开始的内存单元的内容。

还是用 1000:100 来举例子,输出 -e 1000:100 后按下回车键。

如上图所示,可以看到我们先输入了一次 -e 1000:100 这个指令,然后按下了回车键。

注意,如果这里你按下了回车键,就相当于整个 -e 改写的过程已经完成。

如果你想要继续改写后面内存中的值,你需要按下空格键。

我们改写了 1000:100 之后的内存值,然后使用 -d 1000:100 查看我们改写的内容是否生效。

-e 命令还可以支持写入字符,比如我们可以向 1000:0 这个位置开始写入数值和字符,-e 1000:0 1 ‘a' 2 ‘b' e ‘c' 。

如上图所示,当我们向内存写入字符 ‘a' ‘b' ‘c' 的时候,会自动转换为 ASCII 码进行存储,在最右侧可以找到刚刚写入的字符。

Debug -u

如何向内存中写入一段机器码呢?比如我们想要在内存中写入一段机器码。

我们可以使用 -e 来进行写入,向内存中写入 b8 01 00 b9 02 00 01 c8 这个机器码,如下所示

我们使用 -e 写入之后,使用 -d 查看内存值,可以发现我们刚刚写入的值,但是却看不到机器码,所以机器码该如何看呢?

别急,还有个 -u 命令,这个就是看机器码的,如下图所示,我们使用 -u 命令显示我们写入的机器码。

可以看到 1000:0000 ~ 1000:0006 这个内存地址使我们写入的机器码,-u 这个命令就是将内存单元的内容翻译为汇编指令并显示。

-u 输出的结果分为三部分显示:

  • 最左侧是每一条机器指令的地址;
  • 中间是机器指令;
  • 最右侧是机器指令执行的汇编指令。

1000:0 处存放的是写入的机器码 B8 01 00 组成的机器指令,对应的汇编指令是 MOV AX,0001。

1000:0003 处存放的是写入的机器码 B9 02 00 组成的机器指令,对应的汇编指令是 MOV CX,0002。

1000:0006 处存放的是写入的机器码 C1 C8 所组成的机器指令,对应的汇编指令是 add ax,cx。

Debug -t

上面介绍的一系列指令包括我们上面提到的 Debug -e 机器码都是向内存中进行写入,那么如何执行这些指令呢?

我们可以使用 Debug -t 来执行写入的指令。使用 Debug -t 可以执行由 CS:IP 指向的指令。

既然是 -t 能够执行从 CS:IP 指向的命令,所以我们有必要将 CS:IP 指向 1000:0(因为我们前面将指令写在了 1000:0 处)。

首先我们需要执行 -r cs 1000 ,-r ip 0 把 CS:IP 赋值为 1000:0。

然后执行 -t 指令,下图是已经执行过的指令截图。

可以看到,执行完 -t 指令之后,MOV AX,0001 这条指令被执行,当前 AX 寄存器的内容变为了 0001,这条汇编指令的意思就是把 0001 移动到 AX 寄存器中。

继续执行 -t 之后,我们可以看到寄存器的变化。

Debug -a

毕竟机器指令不是那么好懂,写入很不方便,所以有没有办法能够支持我们直接写入汇编指令呢?还真有,Debug 提供了 -a 这种方式来实现汇编指令的写入。如下图所示

可以看到,我们使用了 -a 命令来对 1000:0 进行写入,分别输入 mov ax,1 mov bx,2 mov cx,3 add ax,bx add ax,cx add ax,ax 指令,然后按回车进行确定执行。

我们使用 -d 1000:0 f 可以看到从偏移地址 0 处开始的第 f 个内存指令(因为最大写入的地址只是 f)。

上图中的 1000:000F 为什么有值呢,因为我们上面已经执行过这个写入了。

另外,使用 -a 可以从一个预设的地址处开始输入指令。

总结

今天和大家聊了一下 Debug 的基本用法,主要包括

-r 查看、修改寄存器中的内容

-d 查看内存中的指令

-e 修改内存中的内容

-u 可以将内存中的内容解释为机器指令和对应的汇编指令

-t 执行 CS:IP 处的指令

-a 以汇编得形式向内存写入内容

汇编指令的选项有很多,上面介绍的这些属于经常用到的指令,这些指令要能够熟练使用。

以上就是汇编语言学习手把手的Debug教程的详细内容,更多关于汇编语言Debug教程的资料请关注我们其它相关文章!

(0)

相关推荐

  • 汇编语言功能用循环累加实现乘法

    目录 问题1:编程计算2的2次方,结果存在ax中 分析:用2+2实现 问题2:编程实现2的12次方 分析:用loop实现 问题3:编程实现123*236,结果存在ax中 分析:用236相加123次的计算次数比较少,节约计算资源 问题4:计算ffff:0006单元中的数乘以3,结果存储在dx中 1.判断数据是否能够存储 2.判断数据相加是否能够位数相同 问题5:计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中 1.运算的结果是否超出寄存器的范围 2.能否直接相加dx中的数据 问题6

  • 汇编语言入门汇编指令及寄存器详解教程

    目录 前言 什么是汇编语言 汇编语言产生的原因 汇编与二进制的关系 寄存器 寄存器作用 存取速度比较 寄存器分类 常用寄存器用途 寄存器EAX.AX.AH.AL的关系 汇编语言指令 数据传送指令 算术运算指令 逻辑运算指令 循环控制指令 转移指令 linux 和 windows 下汇编的区别 总结 前言 我们大都是被高级语言惯坏了的一代,源源不断的新特性正在逐步添加到各类高级语言之中,汇编作为最接近机器指令的低级语言,已经很少被直接拿来写程序了,不过我还真的遇到了一个,那是之前的一个同事,因为在

  • 汇编语言显示功能实现教程详解

    目录 问题1 1 如何确定字符要显示的位置 确定3行字符在每一行的起始位置 确定3行字符在屏幕中的哪一行 2 如何确定字符要显示的颜色属性 问题2: 分析: 问题1 在屏幕中间分别显示绿底,绿底红色,白底蓝色的字符串"Welcome to masm!" 分析: 1 如何确定字符要显示的位置 在80*25的彩色字符模式显示缓冲区在内存地址的B8000H~BFFFFH共32KB的空间中 在该模式下,显示器可以显示25行,80列 所以在一行中就有80个字符,共占据160个字节,每个字符低位字

  • TensorFlow深度学习另一种程序风格实现卷积神经网络

    import tensorflow as tf import numpy as np import input_data mnist = input_data.read_data_sets('data/', one_hot=True) print("MNIST ready") n_input = 784 # 28*28的灰度图,像素个数784 n_output = 10 # 是10分类问题 # 权重项 weights = { # conv1,参数[3, 3, 1, 32]分别指定了fi

  • 汇编语言功能字符串大小写转换实现实例详解

    目录 问题1:将data段中的第一个字符串转换成大写,第二个字符串转换成小写 问题2:将data段中每个单词的头一个字母改成大写字母 问题3:将data段中每个单词改为大写字母 问题4:将data段中每个单词的前4个字母改为大写字母 问题5:设计一个子程序,将一个全是字母的字符串转化成大写 问题6:设计一个子程序,将一个全是字母,以0结尾的字符串,转化成大写 复杂一点的对结构化数据的版本 问题1:将data段中的第一个字符串转换成大写,第二个字符串转换成小写 分析: 如何转换成大小写 如果利用A

  • 汇编语言学习手把手的Debug教程

    目录 Debug 是什么 Debug 实战 Debug -r Debug -d Debug -e Debug -u Debug -t Debug -a 总结 关于汇编的第一篇文章: 爱了爱了,这篇寄存器讲的有点意思 Hello大家好,我是程序员cxuan!我们上篇文章了解了一下基本的寄存器,这篇文章我们来进行实际操作一下. 原文链接:https://mp.weixin.qq.com/s/PQzuKtSiHwZleTosvop68A 我们以后将会用到很多 Debug 命令,这里我们先来熟悉一下它们

  • 汇编语言学习assume的作用详解

    assume 的作用是关联段名与段寄存器. 如果你在数据段中定义了变量名,比如: x db 0 而你在代码中,需要直接使用这个变量名,比如: mov al, x 那么,汇编程序在汇编时,就会报告错误. 因为,mov指令中遇到 x 这个变量名时,汇编程序不知道它要用哪个段寄存器作为段地址. 所以: 若要用变量名直接访问,或使用语句标号(比如你例子中的标号 start)就必须要在assume伪指令中将这些变量或标号所在段的段名,与段寄存器名关联,否则会出错. 如果你不使用段中的变量名,可以不关联这个

  • 汇编语言学习心得

    汇编语言 汇编语言(assembly language)是一种用于电子计算机.微处理器.微控制器或其他可编程器件的低级语言,亦称为符号语言.在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址.在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令.特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植. CPU的组成 CPU是由运算器(信息处理).控制器(控制器件工作).寄存器(信息存储)等器件组成,他们之间通过总线相连

  • Intellij IDEA远程debug教程实战和要点总结(推荐)

    远程调试,特别是当你在本地开发的时候,你需要调试服务器上的程序时,远程调试就显得非常有用. JAVA 支持调试功能,本身提供了一个简单的调试工具JDB,支持设置断点及线程级的调试同时,不同的JVM通过接口的协议联系,本地的Java文件在远程JVM建立联系和通信.此篇是Intellij IDEA远程调试的教程汇总和原理解释,知其然而又知其所以然. 本机Intellij IDEA远程调试配置 1,打开Inteliij IDEA,顶部菜单栏选择Run-> Edit Configurations,进入下

  • 微信小程序学习之wxs使用教程

    什么是wxs? wxs(WeiXin Script)是小程序的一套脚本语言, 结合WXML, 可以构建出页面结构. wxs标签 <wxs module="utils" src="../../wxs/test.wxs"></wxs> module属性: 当前标签的模块名, 建议该值唯一, 若存在同名的模块名,则按照先后顺序覆盖(后者会覆盖前者). src属性: a. 只能引用.wxs文件, 且必须是相对路径; b. wxs模块均为单例, wxs

  • 人工智能学习Pytorch进阶操作教程

    目录 一.合并与分割 1.cat拼接 2.stack堆叠 3.拆分 ①Split按长度拆分 ②Chunk按数量拆分 二.基本运算 1.加减乘除 2.矩阵相乘 3.次方计算 4. clamp 三.属性统计 1.求范数 2.求极值.求和.累乘 3. dim和keepdim 4.topk和kthvalue 5.比较运算 6.高阶操作 ①where ②gather 一.合并与分割 1.cat拼接 直接按照指定的dim维度进行合并,要求除了所需要合并的维度之外,其他的维度需要是一样的 2.stack堆叠

  • python深度学习tensorflow安装调试教程

    目录 正文 一.安装anaconda 二.安装tensorflow 三.调试 正文 用过一段时间的caffe后,对caffe有两点感受:1.速度确实快; 2. 太不灵活了. 深度学习技术一直在发展,但是caffe的更新跟不上进度,也许是维护团队的关系:CAFFE团队成员都是业余时间在维护和更新.导致的结果就是很多新的技术在caffe里用不了,比如RNN, LSTM,batch-norm等.当然这些现在也算是旧的东西了,也许caffe已经有了,我已经很久没有关注caffe的新版本了.它的不灵活之处

  • python深度学习tensorflow入门基础教程示例

    目录 正文 1.编辑器 2.常量 3.变量 4.占位符 5.图(graph) 例子1:hello world 例子2:加法和乘法 例子3: 矩阵乘法 正文 TensorFlow用张量这种数据结构来表示所有的数据. 用一阶张量来表示向量,如:v = [1.2, 2.3, 3.5] ,如二阶张量表示矩阵,如:m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],可以看成是方括号嵌套的层数. 1.编辑器 编写tensorflow代码,实际上就是编写py文件,最好找一个好用的编辑器

  • java程序员必会的远程debug教程

    目录 正文 启动添加参数 配置idea 点击 editConfigurations... 点击左上角的+号,选择Remote Jvm Debug 填写地址和端口号 启动debug模式 测试 正文 现在都是拆分的比较细的微服务了,当系统运行在测试环境出现问题的时候,就需要按照日志来分析出什么问题了.有的能看出来,要是年久失修的老项目,那么说不定连log都没有.纯纯的看源码找问题,效率就很低了. 其实这个时候还可以远程debug,来更精确的定位问题.效率也是高高滴. 这个之前在工作中其实一直在使用,

  • 王爽 汇编语言学习笔记(详细)

    王爽汇编语言第三版是一款高清完整版的专业编程图书,该书结构设计合理,内容全面涵盖知识点丰富,适合自学者使用,有需要者快来 一.基础知识 1.指令 机器指令:CPU能直接识别并执行的二进制编码 汇编指令:汇编指令是机器指令的助记符,同机器指令一一对应. 指令:指令通常由操作码和地址码(操作数)两部分组成 指令集:每种CPU都有自己的汇编指令集. 汇编语言由3类指令组成. 汇编指令 伪指令:没有对应的机器码,由编译器执行,计算机并不执行 其他符号:如+.-.*./等,由编译器识别,没有对应的机器码.

随机推荐