本系列是北航计算机学院于 2024 年春季学期开设的一般专业课《X86汇编程序设计》课程的实验报告记录,由于学习过程中掌握并不牢靠,如有错误请读者不吝赐教!

这所谓“水印”真逆天吧,写个小文儿都这么麻烦

X86汇编程序设计第一次实验作业

MASM编程环境

将 MasmForDOSbox2022.rar 中的整个文件夹解压至目录下,并通过安装程序安装 DOSBox0.74,构建实验环境。

image-20240320141831181

启动 DOSBox 并进入 Masm/BIN 目录进入工作环境,完成 MASM 编程环境的配置。

mount c c:/masm
c:
cd bin
dir

image-20240320142323611

程序汇编链接及运行

修改样例程序中变量 MY_NAME 的部分使其包含班号学号。

image-20240320163159704

保存后通过 masm <filename> 进行汇编操作:

image-20240320143015012

汇编后使用 link <filename> 指令进行链接操作,生成可执行文件:

image-20240320143326544

最后直接执行文件,得到结果:

image-20240320163302059

DEBUG与跟踪执行

使用 DEBUG.EXE 对 程序进行调试执行操作。下面是一些常用指令:

-t:单步执行

-g <addr>:执行到 addr 指向的指令地址

-u <addr>:查看以 addr 为首的一段指令段内容

-d <addr>:查看以 addr 为首的一段内存段/堆栈段内容

-r <reg>:修改某寄存器的内容;不加 reg 会查看当前执行状态

-a <addr>:修改 addr 偏移处指令的内容

-e <addr>:修改 addr 偏移处内存单元的内容

-q:退出 debug

首先修改待排序的数组,使用 -e 指令修改原有内存单元 078A:001C、078A:001D 的值,放入字 1368,覆盖原有的单字 0FFFFH

image-20240320163402413

然后对原本位于 0051H 的 JBE 指令修改为 JAE 指令,修改后注意到实际上其变化为了等价的 JNB 指令

image-20240320152628077

首先在单步执行到排序前先查看数组的内存单元:

image-20240320163429001

然后再执行到断点 078A:0067 处,即排序过程结束后进入 EXIT 标号的指令处:

image-20240320163505178

可以看到位于 078A:0020 的数据已经排序为了最小的 0 值,位于 078A:0002 的数据是最大的 03321H,说明数组已经按照降序排列水印字的位置也已经从 078A:001C 移动到了 078A:0004 处。

段间转移及调用指令解读

首先修改双字变量 ADDI 的值(位于内存 078A:003F ~ 078A:0042 中),内容修改为十六进制的学号

image-20240320163554887

修改至 JMP 处后单步执行,执行 JMP 时程序完成了一次 FAR 跳转即段间转移,地址值被设置为了 ADD1 所指向内存的值 2137:xxxx,段地址为 2137,段内偏移为 xxxx,如图:

image-20240320163649996

修改至 CALL 处后单步执行,执行 CALL 时程序先将当前的 CS、IP 存储至栈顶,然后再完成跳转(FAR,段间转移),地址同样被设置为 2137:xxxx,如图:

image-20240320163743635

可以注意到在执行 CALL 指令后,SP 寄存器的值减少了 4,这个 4 就存储了 CS 和 IP 的值,等待 RETF 调用时取出并返回调用者地址;下图中调用了两次 CALL 指令,所以 SP 减少了 8,查看栈顶数据,发现栈中已经存放了两组 3A00 8F07,即 078F:003A,注意到这就是 CALL 指令后一条指令的地址,它表明了返回时应跳转的 CS:IP

image-20240320163809978

实验一就水完了。