《汇编语言》第3章 寄存器(内存访问)——实验2 用机器指令和汇编指令编程

                                        实验2 用机器指令和汇编指令编程

1. 预备知识:Debug的使用
前面实验中,讲了Debug一些主要命令的用法,这里,再补充一些关于Debug的知识。
(1)关于D命令。
从上次实验中,我们知道,D命令是查看内存单元的命令,可以用:
“d 段地址:偏移地址”的格式查看指定的内存单元的内容,上次实验中,D命令后面的段地址和偏移地址都是直接给出的。
现在,我们知道段地址是放在段寄存器中的,在D命令后面直接给出段地址,是Debug提供的一种直观的操作方式。D命令是由Debug执行的,Debug在执行“d 1000:0”这样的命令时,也会先将段地址1000H送入段寄存器中。
Debug是靠什么来执行D命令的?当然是一段程序。
谁来执行这段程序?当然是CPU。
CPU在访问内存单元的时候从哪里得到内存单元的段地址?从段寄存器中得到。
所以,Debug在其处理D命令的程序估中,必须有将段地址送入段寄存器的代码。
段寄存器有4个:CS,DS, SS,ES,将段地址送入哪个段寄存器呢?
首先不能是CS,因为CS:IP必须指向Debug处理D命令的代码,也不能是SS,因为SS:SP要指向栈顶。这样只剩下了DS和ES可以选择,放在哪里呢?我们知道,访问内存的指令如“mov ax,[0]”等一般都默认段地址在ds中,所以Debug在执行如“d 段地址:偏移地址”这种D命令时,将段地址送入ds中比较方便。
D命令也提供了一种符合CPU机理的格式:”d 段寄存器:偏移地址“,以段寄存器中的数据为段地址SA,列出从SA:偏移地址开始的内存区间中的数据。以下是几个例子。

⑴  -r ds
     :1000
     -d ds:0      ;查看从1000:0开始的内存区间中的内容
⑵  -r ds
     :1000
     -d ds:10 18 ;查看1000:10~1000:18中的内容
⑶  -d cs:0     ;查看当前代码段中的指令代码
⑷  -d ss:0     ;查看当前栈段中的内容
(2)在E,A,U命令中使用段寄存器。
在E,A,U这些可以带有内存单元地址的命令中,也可以同D命令一样,用段寄存器表示内存单元的段地址,以下是几个例子。
⑴  -r ds
     :1000
     -d ds:0 11 22 33 44 55 66   ;在从1000:0开始的内存区间中写入数据
⑵  -u cs:0   ;以汇编指令的形式,显示当前代码段中的代码,0代码的偏移地址
⑶  -r ds
     :1000
     -a ds:0   ;以汇编指令的形式,向从1000:0开始的内存单元中写入指令
(3)下一条指令执行了吗?
在Debug中,用A命令写一段程序:
mov ax,2000
mov ss,ax
mov sp,10 ;安排2000:000~2000:000F为栈空间,初始化栈顶
mov ax,3123
push ax
mov ax,3366
push ax   ;在栈中压入两个数据
仔细看下面中单步执行的结果,你发现了什么问题?

在用T命令单步执行mov ax,2000后,显示出当前CPU各个寄存器的状态和下一步要执行的指令:mov ss,ax;
在用T命令单步执行mov ss,ax后,显示出当前CPU各个寄存器的状态和下一步要执行的指令......,在这里我们发现一个问题:mov ss,ax的下一条指令应该是mov sp,10,怎么变成了mov ax,3123?
mov sp,10到哪里去了?它被执行了吗?
我们再仔细观察,发现:
在程序执行前,ax=0000, ss=073F,sp=00FD,而执行后ss=2000,sp=0010。ss变为2000是正常的,这正是mov ss,ax的执行结果。可是sp变为0010是怎么回事?在这期间,能够将sp设为0010的只有指令mov sp,10,看来,mov sp,10一定是得到了执行。
那么,mov sp,10是在什么时候被执行的呢?当然是在mov ss,ax之后,因为它就是mov ss,ax的下一条指令。显然,在用T命令执行mov ss,ax的时候,它的下一条指令mov sp,10也紧接着执行了。
整理一下我们分析的结果:在用T命令执行mov ss,ax的时候,它的下一条指令mov sp,10也紧接着执行了。一般情况下,用T命令执行一条指令后,会停止继续执行,显示出当前CPU各个寄存器的状态和下一步要执行的指令,但T命令执行mov ss,ax的时候,没有做到这一点。
不单是mov ss,ax,对于如mov ss,bx, mov ss,[0], pop ss等指令都会发生上面的情况,这些指令有哪些共性呢?它们都是修改栈段寄存器SS指令。
为什么会这样呢?要想彻底说清楚这里面的来龙去脉,在这里还为时过早,因为这涉及我们在以后的课程中要深入研究的内容:中断机制,它是我们后半部分课程中的一个主题 。现在我们只要知道这一点就可以了:Debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。

2 实验任务
(1)使用Debug,将下面的程序段写入内存,逐条执行,根据指令执行后的实际运行情况填空。
mov ax,ffff
mov ds,ax

mov ax,2200
mov ss,ax

mov sp,0100

mov ax,[0]      ;ax=COEA
add ax,[2]      ;ax=COFC
mov bx,[4]      ;bx=30F0
add bx,[6]      ;bx=6021

push ax         ;sp=00FE;修改的内存单元的地址是2200:00FE内容为COFC
push bx         ;sp=00FC;修改的内存单元的地址是2200:00FC内容为6021
pop ax          ;sp=00FE;ax=6021
pop bx          ;sp=0100;bx=C0FC

push [4]        ;sp=00FE;修改的内存单元的地址是2200:00FE内容为30F0
push [6]        ;sp=00FC;修改的内存单元的地址是2200:00FC内容为2F31

 

 

(2)仔细观察图3.19中的实验过程,然后分析;o wftc2000:0~2000:f中的内容会发生改变?

其实这些就是寄存器的信息,因为t是会使程序中断的,了解中断请跳看到12章。

所以每次执行t的时候,程序都会保存一次寄存器的信息。

执行mov ss,ax 发生了变化,通过观察此时2000:0006存放的是ax的值。2000:000a存放的是ip的值。2000:000c存放的是cs的值。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值