实验2
一、实验结论
1、实验任务1
源代码如下:
1 assume cs:code 2 code segment 3 mov ax, 0b810h 4 mov ds, ax 5 6 mov byte ptr ds:[0], 1 7 mov byte ptr ds:[1], 1 8 mov byte ptr ds:[2], 2 9 mov byte ptr ds:[3], 2 10 mov byte ptr ds:[4], 3 11 mov byte ptr ds:[5], 3 12 mov byte ptr ds:[6], 4 13 mov byte ptr ds:[7], 4 14 15 mov ah, 4ch 16 int 21h 17 code ends 18 end
汇编结果如下图:
链接结果如下图:
运行结果如下图:
使用u命令精确反汇编如下图:
查看PSP如下图:
使用g命令执行到退出前如下图:
2、实验任务2
源代码如下:
assume cs:code code segment mov ax, 0b810h mov ds, ax mov bx, 0 mov ax, 101H mov cx, 4 s: mov [bx], ax add bx, 2 add ax, 101H loop s mov ah,4ch int 21h code ends end
汇编结果如下图:
链接结果如下图:
运行结果如下图:
使用debug调试如下图:
ex2与ex1实现的功能是相同的,但ex2通过循环命令loop的使用,避免了ex1中的重复操作,使得程序更简洁、易读。
3、实验任务3
源代码如下:
assume cs:code code segment mov ax, 0b800h mov ds, ax mov bx, 7B8H mov ax, 437H mov cx, 16 s: mov [bx], ax add bx, 2 loop s mov ah,4ch int 21h code ends end
运行结果如下图:
将填充的数据改为0239H后运行结果如下图:
将填充的数据改为0437H后运行结果如下图:
根据实验结果可以猜测,高位字节存放的是色彩信息,地位字节存放的是需要显示的字符。
4、实验任务4
源代码如下:
; ex2.asm assume cs:code code segment mov ax, 0 mov ds, ax mov bx, 200H mov ax, 0 mov cx, 40H s: mov [bx], ax add ax, 1 add bx, 1 loop s mov ah,4ch int 21h code ends end
汇编与链接结果如下图:
使用u命令精确反汇编后,使用g命令执行到退出前,并使用d命令查看0:200至0:23F,可见成功写入,如下图:
5、实验任务5
最终源代码如下:
assume cs:code code segment mov ax, cs mov ds, ax mov ax, 0020H mov es, ax mov bx, 0 mov cx, 17H s: mov al, [bx] mov es:[bx],al inc bx loop s mov ax, 4c00H int 21H code ends end
由于程序已CS:IP为入口,因此第一空处填cs。
循环次数即为代码段长度,因此可先在第二空处填入任意数字,然后汇编、链接,并通过观察cx寄存器的值使用u命令反汇编,如下图:
可见,需要复制的范围为076A:0000至076A:0016,共17H个字节。故第二空处填17H。
再次汇编、链接后,运行结果如下图,可见成功完成了复制:
二、实验总结
在进行实验任务1、实验任务2,即修改显存时,会发现出现以下现象:直接执行程序可以观察到屏幕上的显示出现变化,而使用t命令单步执行时则观察不到,且使用d命令查看显存区的结果也与预期不符。我认为这是由于dosbox中dos系统默认运行在虚拟显卡的字符模式下,显存中的每一个单元对应屏幕上的每一个字符。debug的t命令会显示各个寄存器的状况,这些显示内容会覆盖我们写入的内容,或使得屏幕滚动,将我们写入的内容滚动到可视区域外,进而被丢弃。以上是我个人的猜想,具体原因还需要更进一步的验证。