[Assembly Language] 实验1 用机器指令和汇编指令编程

Task 1 使用Debug工具执行汇编指令并观察寄存器中内容变化

使用Debug,将下面的程序段写入内存,逐条执行,观察每条指令执行后CPU中相关寄存器中内容的变化

机器码 汇编指令
b8 20 4e mov ax, 4E20H
05 16 14 add ax, 1416H
bb 00 20 mov bx, 200H
01 d8 add ax, bx

使用 DOSbox 进入 debug 模式,输入 -r 可以看到寄存器中的初始数值

使用 -e 写入机器指令,并修改 CS:IP,使用 -t 命令执行写入的机器指令

 

使用 -a 写入汇编指令,使用 -t 命令执行写入的汇编指令

 

Task 2 计算 2 的 8 次方

 使用一下 3 条指令写入从 2000:0 开始的内存单元中,利用这 3 条指令计算 2 的 8 次方

mov ax, 1
add ax, ax
jmp 2000:0003

分析:第一条指令给 ax 赋初值 1,第二条指令 ax 的值变为 2 倍,第三条指令跳转到第二条指令再次执行
根据三条指令的功能,写出汇编程序,逐步执行结果如图所示

 

 

Task 3 查看ROM的生产日期,并尝试修改

PC机主板上的ROM中写着一个生产日期,在内存 FFF00H~FFFFFH 的某几个单元中,找到这个生产日期并阐释修改它

使用 -d 命令查找,发现日期在 FFFF0H~FFFFFH 中,使用 -e 命令尝试改变无效

 

 原因分析:ROM 为只读存储器,只读存储器中的值无法改变

 

Task 4 从不同地址开始填写不同数据

向内存从B8100H开始的单元中填写数据,可以看到窗口第二行出现颜符号,改变填写的数据,符号改变

改变开始填入数据的地址,变化如下

原因分析:A0000H~BFFFFH为 显存地址空间,改写其中的数据会被显示到窗口中

 

Task 5 使用 debug 执行程序并填写运行结果

使用 -e 将 0022:0~0022:7 连续 8 个字节的数据修改为 50H, 51H, 52H, 53H, 54H, 55H, 56H, 57H,并查看是否正确写入

 

写入如下程序:

mov ax, 0022
mov ds, ax
mov ax, 2200
mov ss, ax
mov sp, 0100
mov ax, [0]
add ax, [2]
mov bx, [4]
add bx, [6]
push ax
push bx
pop ax
pop bx
push [4]
push [6]

 

 

使用 -t 逐条执行汇编指令

 

运行结果填空如下,与理论结果一致

汇编指令 填写内容 分析
mov ax, 0022 / /
mov ds, ax / 设置数据段地址为0022
mov ax, 2200 / /
mov ss, ax / 设置栈顶所在段为2200
mov sp, 0100 / 栈的偏移地址为0100
mov ax, [0] ax = 5150 把地址00220H~00221H中的两个字节赋值给ax
add ax, [2] ax = A4A2 ax加上地址00222H~00223H的两个字节
mov bx, [4] bx = 5554 /
add bx, [6] bx = ACAA /
push ax sp = 00FE;修改的内存单元的地址为 220FEH 内容为 A4A2 栈中push入ax,栈顶sp位移两个字节,指向地址内容为 A4A2
push bx sp = 00FC;修改的内存单元的地址为 220FCH 内容为 ACAA  /
pop ax sp = 00FE;ax = ACAA  栈顶的两个字节赋值给ax,220FCH~220FDH中的内容
pop bx sp = 0100;bx = A4A2  /
push [4] sp = 00FE;修改的内存单元的地址为 220FEH 内容为 5554  /
push [6] sp = 00FC;修改的内存单元的地址为 220FCH 内容为 5756  /

 

 

Task 6 观察图中实验过程回答问题

汇编程序如下

mov ax, 2000
mov ss, ax
mov sp, 10
mov ax, 3123
push ax
mov ax, 3366
push ax

运行中间结果如图所示

 

指令 mov ss, ax 和 mov sp, 10 一起被执行了,并且地址20000H开始的16个字节出现垃圾数。

原因分析:通过仔细观察垃圾数,发现栈中的数据依次为01、CS、IP,通过翻阅书本后面的章节了解到为中断机制中断内容,01位标志寄存器TF的值。t 命令执行时,TF被设置为01,使得CPU执行完一条指令就引发单步中断,并等待下一个命令。但是响应中断存在特殊情况,在执行完 mov ss, ax 之后 CPU 不会响应单步中断。因为 ss:sp 联合指向栈顶,对它们设置应该连续完成。如果 CPU 响应该次中断,将标志寄存器、CS、IP压入栈中,ss:sp 指向的是不正确的栈顶,引起错误。因此,CPU 在执行完mov ss, ax 之后,为了规避出错,不响应中断,执行完mov sp, 10之后再引发中断过程。CPU 每次引发中断过程,会自动把TF、CS、IP压入栈中,观察后续指令执行后地址20000H~2000FH中的值,栈元素前面几个值即为每次中断过程保存的数据。

 

posted @ 2020-10-09 18:11  Kusunoki  阅读(212)  评论(1)    收藏  举报