实验一 查看CPU和内存,用机器指令和汇编指令编程
我们开始实验之前,需要准备好使用的工具,如果你是win2000之类的操作系统可以直接打开cmd命令行输入debug即可打开汇编指令的界面,但是我现在使用的是win11的系统,就需要装一个Dosbox的软件。
首先进入Dosbox,逐个尝试查看命令:
-R | 查看、改变CPU寄存器的内容 |
-D | 查看内存中的内容 |
-E | 改写内存中的内容 |
-U | 将内存中的机器指令翻译为汇编指令 |
-T | 执行一条机器指令 |
-A | 一会变得格式在内存中写入一条机器指令 |
-r命令:
- -r 查看所有寄存器的信息
- -rax 查看寄存器ax的信息并可以在“:”后直接进行修改
-d命令:
- -d 直接查看DS:0100位置内存中的内容
- -d 【段地址】:【偏移地址】 直接查看所选内存地址
- -d 【段地址】:【起始偏移地址】 【结束偏移地址】 查看所选范围的内存
- 在使用过-d命令后直接使用-d命令 输出上一次-d命令的后续内存
-e命令:
- -e 【段地址】:【偏移地址】 a b c d e f ...... 将所选内存替换为a b c d......(可以是16进制数也可以是字符,还可以是一个字符串)
- -e 【段地址】:【偏移地址】 可以直接在出现“:”后逐个改写内存
-u命令:
- -u 【段地址】:【偏移地址】 将指定的内存中的机器指令翻译为汇编指令
-t命令:
- -t 直接执行cs:ip处的汇编指令
-a命令:
- -a 出现cs:ip地址后直接写汇编指令,自动更新ip的值,可以继续写汇编指令。
实验2 用机器指令和汇编指令编程
(1)D命令补充:
我们知道D命令可以直接执行例如-d 1000:0这样的操作,那么CPU是从哪个段寄存器中找到1000这个段地址呢?,首先不是cs,因为cs已经指向了这个d命令的代码,SS要指向栈顶,所以只有DS和ES,我们还知道如果执行类似mov ax,[o]这样的指令时,默认[0]的段地址在ds中,所以在执行-d 1000:0时先将1000送入ds中,再执行-d命令。
(2)在E、A、U命令中使用段寄存器
-r ds
:1000
-e ds:0 11 22 33 44 55 66 #从1000:0开始的内存区间中写入数据
-u cs:0 #以汇编指令的形式,显示当前代码段中的代码
-r ds
:1000
-a ds:0 #以汇编指令的形式,从1000:0开始的内存单元中写入指令
执行结果:
(3)下一条指令执行了吗?
我们用a命令输入一些指令并用t命令执行:
mov ax,2000
mov ss,ax
mov sp,10
mov ax,3123
结果如下:
我们可以看到,在执行mov ss,ax后,下一行的mov sp,10并没有紧接着显示,而是到了再下一行的mov ax,3123。我们观察ax可以看到实际上mov sp,10这一行代码是被执行过的。那么我们可以知道:debug的T命令在执行修改寄存器SS的指令时,下一条指令会紧接着被执行,一次执行两条指令。具体为什么会在后面的中断机制中解释。
实验四
(1)(2)编程,向内存0:200~0:23F依次传送数据0~63(3FH),只能使用9条指令,伪指令不计入。
assume cs:code
code segment
mov ax,0020H
mov ds,ax
mov bx,0
mov cx,64
s: mov [bx],bx
inc bx
loop s
mov ax,4c00H
int 21H
code ends
end
(3)补全代码
mov ax,cs 直接用cs就是代码开始的地方
mov cx, 23 不能直接使用cx,cx是整个代码的长度