【实验报告】微处理器原理与应用 CPUHomework1.2 上篇【掌握DEBUG基本命令及其功能 查看CPU和内存 用机器指令和汇编指令编程】

实验报告

课程名称:微处理器原理与应用
实验名称:CPUHomework1.2 掌握 DEBUG 基本命令及其功能

【实验目的】

  1. 掌握 DEBUG 基本命令及其功能
  2. 掌握 Win11 使用 DEBUG 功能

【实验要求】

  1. 【上篇】查看CPU和内存,用机器指令和汇编指令编程
  2. 【下篇】用机器指令和汇编指令编程

上篇【查看CPU和内存,用机器指令和汇编指令编程】

【实验具体内容1】

1) 预备知识

汇编程序指令:

  1. mov 传送指令 mov A,B 即B值赋给A

坑:mov不是转移指令,可以修改IP,或同时修改CS和IP的指令统称为转移指令,也即转移指令是可以控制CPU执行内存中某处代码的指令

8086CPU的转移行为有两类:

  • 只修改IP(Instruction pointer)的段内转移,如 jmp ax
  • 同时修改CS(code segment register)和IP的段间转移,如 jmp 1000:0

而其转移指令分为:

  • 无条件转移指令(如 jmp)
  • 条件转移指令
  • 循环指令(如 loop)
  • 过程
  • 中断

在汇编语言中mov指令是数据传送指令,也是最基本的编程指令,用于将一个数据从源地址传送到目标地址

  1. add ax,bx (ax = ax + bx)

  2. sub ax,bx (ax = ax - bx) (坑)

  3. jmp 无条件转移(跳转)

2)Debug的使用

1. 什么是Debug

Debug 是 DOS、Windows 都提供的实模式(8086 方式)程序的调试工具。使用它,可以 查看 CPU 各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行

2.所用Debug六大功能
  • -R (register):查看,改变CPU寄存器的内容
  • -D (dump):查看内存中的内容(16进制显示)
  • -E (enter):改写内存中的内容(向指定编号的内存中进行数据的写入操作)
  • -U (unassemble)(反汇编):将内存中的机器指令翻译为汇编指令来进行查看
  • -T (trace)(跟踪执行):单步执行一条机器指令
  • -A (assemble)(逐行汇编):以汇编指令的格式在内存中写入一条机器指令
3.进入Debug

Debug是在DOS方式下使用的程序

我们在进入 Debug 前,应先进入到 DOS 方式。
现在用以下方式不可以进入 DOS:
① 重新启动计算机,进入 DOS 方式,此时进入的是实模式的 DOS。
② 在 Windows 中进入 DOS 方式,此时进入的是虚拟 8086 模式的 DOS。

现在我们采用DOSBox的方式进行,键入debug,运行debug程序

4.用R命令查看,改变CPU寄存器的内容
  • 显示 CPU 内部所有寄存器内容和标志位状态;格式为:-r

通用寄存器4个:AX,BX,CX,DX

​ AX,BX,CX,DX为通用寄存器用来保存运算中的中间结果和有效地址。4个寄存器既可以做16位寄存器,也可以做为8位寄存器AL,AH,BL,BH,CL,CH,DH , DL。
​ 在程序设计中,一般把AX用作累加寄存器(Accumulator Register)。BX用作基址寄存器(Base Register),CX用作计数寄存器(Count Register),DX用作数据寄存器(Data Register)

索引(变址)寄存器2个:SI,DI

SI(Source Index):源变址寄存器

DI(Destination Index):目的变址寄存器

指针寄存器2个:SP, BP

SP(Stack Pointer):栈指针寄存器

BP (Base Pointer):基址指针寄存器

IP(Instruction Pointer):指令指针寄存器;始终存放当前指令的下一条指令的起始存储单元的偏移地址

段寄存器4个:
CS(Code Segment):代码段寄存器;装代码段的起始地址
DS(Data Segment):数据段寄存器;装数据段的起始地址
SS(Stack Segment):栈段寄存器;装栈段的起始地址
ES(Extra Segment):附加段寄存器;装附加段的起始地址

程序状态寄存器PSW(Program Status Word)(程序状态字)

值得注意的是:

  1. CS=073F , IP=0100 ,也即内存073F:0100处的指令为CPU当前要读取执行的指令

在所有寄存器的下面我们可以看到CS:IP所指向的内存单元处所存放的机器码 00 00 ,并将之翻译为汇编指令 ADD [BX+SI] , AL 。

  1. 还有就是PSW的值,NV 清除 ; UP 增 ; EI 启用 ; PL 正 ;NZ 非零 ;NA 不进位 ;PO 奇校验 ; NC 不进位
  • 显示并修改某个指定寄存器内容;格式为 -r 寄存器名

修改寄存器ax中的值为1234,并用R命令再次查看

  • 此外,我们还可以修改CS和IP的内容

5.用Debug的D命令查看内存中的内容
  • 格式1:-d 段地址:偏移地址,Debug将列出从指定内存单元开始的128个内存单元的内容

比如说我们想要知道内存10000H处的内容,先将之表示为1000:0的格式,然后键入并回车

可见我们从1000:0开始的内存中目前没有存入数据

于是我将指定的地址改为0:0,键入并回车

现在就可以看见内存0处的内容

  1. 左边的是每行的起始地址
  2. 中间的是从指定地址开始的128个内存内容,并用16进制格式输出,每行的从16的整数倍开始,最多输出16个内存单元的内容。从图中可知,内存0:0单元中的内容是60H,内存0:1单元中的内容是10H,内存0:00:F的内容都在第一行,同理内存0:100:1F的内容都在第二行… 每行中间的-则是为了将每行的输出分为8(07)+8(8F)两部分,让查找单元变得十分方便
  3. 右边的是每个内存单元中的数据对应的可显示的ASCII码字符,如果没有对应的可显示的字符则Debug用"."代替
  4. 值得注意的是内存中的内容时时刻刻都在受系统环境的影响,会发生改变

此外,可以将起始内存地址改为0:8,看看Debug会有怎样的输出

由此可见,Debug将从0:8开始显示,一直到0:87,一共还是128(16 x 8)个字节

此外我们可以发现在此之后继续使用-d命令则会列出后续的128字节内容

  • 格式2:-d 段地址:起始偏移地址 结尾偏移地址,Debug将列出指定范围的内存单元的内容

并且发现指令-d与段地址中间可以无空格

如果想要查看某个内存单元的内容可以有很多方法,这取决于起始位置和偏移量

6.用Debug的E命令改写内存中的内容,同样有两种格式
  • 格式1:-e 起始地址 数据 数据 数据…,

由上图可见我们用E命令修改成功,并且可见我们在指令执行空隙之间可以用回车进行分隔,使指令与返回更清晰,但是在指令输入过程中不能敲回车,否则会有Error

  • 格式2: -e 起始地址,逐个单元相继修改

重新打开一个DOSBox,相继使用D命令和E命令

通过一个一个修改,将前4个内存单元的内容改为86H,可见这样的修改方式十分有趣且便利(doge)

此外,容易认识到在Debug过程中不要轻易按Enter,否则容易在未完全输入好程序时执行,而空格作为常用间隔符可以经常使用

  • 用E命令向内存中写入字符

由上图可知,我向前7个内存空间存入了7个数字与字符

'a’的ASCII码值为61H (97) 'A’的ASCII码值为41H(65) '1’的ASCII码值为31H(49) Bingo!

  • 用E命令向内存中写入字符串

重启一下DOSBox,发现之前的内存数据已被清空(很正常,相当于断电重启)

可见存入的字符串有几个字符,大概就占用几个字节(且为顺序存储)

并且由上图可见DOS不区分单双引号

7.用E命令向内存中写入机器码,用U命令查看内存中机器码的含义,用T命令执行内存中的机器码

机器码也是数据,可以用E命令将机器码写入内存,我们可以尝试从内存1000:0单元开始写入以下机器码:

机器码对应的汇编指令
b80100mov ax , 0001
b90200mov cx , 0002
01c8add ax , cx

而后使用U命令将从1000:0开始的内存单元中的内容翻译为汇编指令并显示出来,

在上图中,我们首先使用了E命令向从1000:0开始的内存单元中写入了b8 01 00 b9 02 00 01 c8 八个字节的机器码,然后用D命令从数据的角度看来以下写入的内容,最后采用U命令查看从1000:0开始的内存单元中的机器指令以及其所对应的汇编指令

  • 格式1为 : -u 段地址:偏移地址

该命令从指定地址开始反汇编32个字节,若地址省略则从上一个U命令的最后一条指令的下一个单元开始开始显示32个字节

  • 格式2为: -u 地址范围

该命令对指定范围的内存单元进行反汇编

且此时 1000:0 6 与 1000:0 7 作用相同

且可见U命令的显示输出分为3部分:

  1. 每一条机器指令的地址
  2. 机器指令
  3. 机器指令所对应的汇编指令

由此我们可以认识到内存中的数据和代码没有任何区别,关键在于如何解释

8.使用T命令可以执行CS:IP指向的指令

格式为: -t,执行指令后,Debug显示输出CPU中寄存器的状态

如上图,

  1. 用E命令向内存中写入8个字节的机器码
  2. 然后用R命令查看CPU中寄存器的状态,其中CS=073FH IP=0100H,指向内存074F0H(073F:0100)
  3. 再用R命令修改CS:IP中的内容,使之指向1000:0
  4. 完成以上步骤后使用T命令执行写入的命令,可以发现b8 01 00 被执行,ax中的内容被改写为1,IP+3变为0003(因为mov ax,0001的指令长度为3个字节),与此同时CS:IP指向下一条指令
  5. 继续使用T命令执行下面的指令

如图,我们执行结束我们输入的指令

####8.用Debug的A命令以汇编指令的形式在内存中写入机器指令

实际上前面我们使用E命令写入了机器指令到内存中,但显然这样做很不方便,因此Debug提供了A命令直接以汇编指令的形式写入,如下图

用A命令写入指令,用D命令查看A命令的执行结果,可以看见我们输入的汇编指令被Debug翻译(汇编)为对应的机器指令,并将其机器码写入内存

格式:-a 段地址:偏移地址

【实验任务】

1)实验源代码

mov ax , 4E20H 
add ax , 1416H 
mov bx , 2000H 
add ax , bx 
mov bx , ax 
add ax , bx 
mov ax , 001AH 
mov bx , 0026H 
add al , bl 
add ah , bl 
add bh , al 
mov ah , 0 
add al , bl 
add al , 9CH 

2)实验代码、过程、相应结果(截图)并对实验进行说明和分析

1 使用Debug将源程序写入内存,逐条执行,观察每条指令执行后CPU中相关寄存器中内容的变化,下面我们使用A命令,并用R命令改变CS:IP的指向,最后使用T命令执行

用A命令,初始地址设置为1000:0,开始时在十六进制数后尝试加上了H,果然系统报错,后将其删掉,成功执行,然后就顺序以汇编指令的形式在内存中写入机器指令

用R命令修改CS和IP中的值,使之指向所设置的初始地址,再用R命令查看一下,No Problem!

用T命令逐条执行前4条指令,并查看指令执行后Debug显示输出的CPU中寄存器的状态

由上图的颜色区分,我们很容易发现 mov 和 add 指令的规律

其中紫色框MOV BX,AX 表示将AX中的数据传送到BX中,发生覆盖(且传送的相当于AX的副本,AX的值并未变化)

同理,我们可以分析上述代码,值得注意的是当 ADD AX,BX执行之后,AX所存的数据发生进位导致溢出

此外,ADD AL,BL也导致了进位,不过未发生溢出

上图中,粉色框ADD AH,AL 表示将BX的低八位BL加到AX的高八位AH

至此,写入的机器指令全部执行完毕

2 将下面的3条指令写入从2000:0开始的内存单元中,利用这三条指令计算2的8次方
mov	ax,1
add	ax,ax
jmp	2000:003

3查看内存中的内容

PC机主板上的ROM中写有一个生产日期,在内存FFF00H~FFFFFH的某几个单元中,请找到这个生产日期并试图改变它 (内存ffff:0005~ffff:000C共8个字节单元中)

显然生产日期确实是写在FFFF:0005 ~ FFFF:000C八个内存单元中

显示的日期是01/01/92,显然与我的电脑生产日期不符,因为我们使用的是DOSBox虚拟环境,内存也是虚拟的,这个日期可能是DOSBox所设置的默认日期

只读存储器(Read-Only Memory,ROM)以非破坏性读出方式工作,只能读出无法写入信息。信息一旦写入后就固定下来,即使切断电源,信息也不会丢失,所以又称为固定存储器。ROM所存数据通常是装入整机前写入的,整机工作过程中只能读出,不像随机存储器能快速方便地改写存储内容。ROM所存数据稳定 ,断电后所存数据也不会改变,并且结构较简单,使用方便,因而常用于存储各种固定程序和数据

现在我们来对其进行修改

本想将生产日期改为18/09/22,结果发现无法修改,这也说明了只读存储器无法写入的特性


在DOSBox的Debug内外使用 wmic bios get description都不行

而在DOS环境下使用 wmic bios get description 可以得到一个描述,也即BIOS目前版本,用Direct X 诊断工具也可以获取电脑的BIOS版本

同理,使用 wmic bios get serialnumber 还可以获取序列号等等信息

WMIC是扩展WMI(Windows Management Instrumentation,Windows管理规范),提供了从命令行接口批命令脚本执行系统管理的支持。在WMIC出现之前,如果要管理WMI系统,必须使用一些专门的WMI应用,比如SMS,或者使用WMI的脚本编程API,或者使用CIM Studio之类的工具。如果不熟悉C++之类的编程语言或VBScript之类的脚本语言,或者不掌握WMI名称空间的基本知识,要使用WMI管理系统是很困难的。WMIC改变了这种情况,为WMI 名称空间提供了一个强大的、友好的命令行接口

总而言之,WMIC是一款命令行管理工具。使用WMIC,我们不但可以管理本地计算机,而且还可以管理同一Windows域内的所有远程计算机(需要必要的权限),而被管理的远程计算机不必事先安装WMIC,只需要支持WMI即可

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zanebla

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值