环境准备
Dosbox
百度网盘链接:pan.baidu.com/s/1GjBCQ6XW… 提取码:z5tc 拿到 DOSBox0.74-win32-installer.exe ,直接安装,无脑下一步即可
debug
将 debug.exe 保存在用于学习的文件夹下,比如 F:\asm 下
然后就可以打开 DOSbox ,命令行输入
mount c: f:\asm 目的是将 f:\asm 挂载到 c 盘上
c: 目的是切换回 c 盘
debug 执行 debug.exe 应用程序
因为挂载的操作是每次打开 DOSBox 都需要做的,如果每次都手动必然很麻烦,所以我们配置一下,让 DOSBox 每次启动时就自动执行 mount c: f:\asm c:
首先找到 C:\Users\[用户名]\AppData\Local\DOSBox\dosbox-0.74.conf
然后编辑该文件,在最后 [autoexec] 处下加上每次启动需要自动执行的代码
实验一
熟悉常用 debug 命令
-
r 可以命令查看和改变 CPU 寄存器内容
-
若想查看所有寄存器的状态,直接输入 r 然后回车即可
-
若想修改某个寄存器内的值,命令行输入 r 寄存器名 + enter,然后出现 : 以提示输入内容,随后输出想给的值 + enter 即可
-
-
d 命令以十六进制格式显示内存内容。可以使用这个命令查看某个内存地址处的内容。
-
可以直接使用 d 命令亦或是指定从何处开始,比如
d 2000:0如果没有指定从何处结束,则展示从起始位置开始的 128 个存储单位内容
展示内容分为三部分,左边为该行起始地址,中间为每一个地址对应的十六进制数,右边是其作为 ASCLL 码代表的含义
-
-
e 以十六进制格式编辑内存内容。可以使用这个命令修改内存中的数据。
-
可以直接在 e 起始地址 数据 数据 数据 …..
-
也可以先 e 起始地址 + enter,然后会逐个提示原来这个位置的内容以及用一个 . 提示输入,按下空格继续输入,回车停止输入
-
可以输入字符串
-
-
u 命令以汇编和机器码混合模式显示内存内容。使用这个命令可以以更详细的方式查看内存中的指令和数据。
-
u 指定位置
-
-
t 命令跟踪指令的执行。使用这个命令可以逐步执行程序,并查看每条指令的执行情况。
- 是执行 CS:IP 指向的指令
-
t 命令跟踪指令的执行。使用这个命令可以逐步执行程序,并查看每条指令的执行情况。
- 是执行 CS:IP 指向的指令
-
a 命令以汇编模式输入指令。可以使用这个命令来编写汇编代码,并将其插入到内存中。
-
a 指定位置
-
| 命令 | 对应完整单词 |
|---|---|
| a | assemble(汇编) |
| d | display(显示) |
| e | edit(编辑) |
| g | go(执行) |
| p | program(程序) |
| q | quit(退出) |
| r | register(寄存器) |
| t | trace(追踪) |
| u | unassemble(反汇编) |
任务
(1)
首先打开 DOSBox,debug,然后使用 a 命令开始编写汇编指令,然后用 r 命令查看 CS:IP 指向的指令
可以看到即将执行的指令就是最开始输入的 mov ax,4e20
接下来我们开始执行指令,观察各寄存器的状态
mov ax 4e20 后 ax 中的值由 0 变为 4e20H
add ax,1416 后 ax 中的值为 4e20H + 1416H = 6236H
mov bx,2000 后 bx 中的值由 0 变为 2000H
add ax,bx 后 ax 的值为 6236H + 2000H = 8236H,而 bx 不变
(t 命令下边的是接下来要执行的指令,上边的才是刚执行完的指令,别搞错了)
mov bx,ax 后 bx 的值变为 8236H
add ax,bx 后本来 ax 的值应该是 8236H + 8236H = 1046CH,然后 8086 CPU的寄存器是 16位大小,超出两字节范围的二进制数不会被存储进寄存器,故第五位十六进制位丢失,最终 ax 的值为 046CH
mov ax,001a 后 ax 的值为 001AH
mov bx,0026 后 bx 的值为 0026H
add al,bl 后 ax 的值为 1AH + 26H = 40H
add ah,bl 后 ax 的值为 2640H,ax 高位被替换为 bl 的值
add bh,al 后 bx 的值为 4026H
mov ah,00 后 ax 的值为 0040H
add al,bl 后 ax 的值为 0066H
add al,9c 后 ax 的值为 0002H,因为 add 指令面对的是 8 位寄存器 al,所以这次运算属于 8 位数据运算,则最终结果 102H 中的第三位十六进制位被舍去。
(2)
将下面 3 条指令写入从 2000:0 开始的内存单元中,利用这 3 条指令计算 2 的 8 次方。
mov ax,1
add ax,ax
jmp 2000:0003
我们先让 CS:IP 指向 2000:0,然后写入指令
我们可以看出 2000:0 开始的代码段其实是一个循环,首先给 ax 赋值 1,然后让其不断自加即乘二。所以我们的目的是让 ax 中的值变为 2 的 8 次方即可。
需要注意的是 2 的 8 次方,十进制表示是 256,而十六进制表示是 100H,所以当 ax 中的值为 100 时则任务完成
(3)
任务三受限于硬件原因,无法完成
(4)
命令行输入 e B810:0000 然后按下回车
紧接着输入 01 然后按下空格
终端上则会出现 01 ASCII码代表的字符
再次输入 01 会发现终端上并没有增加字符,而是先前的字符改变了颜色
以下为输入完的效果