检测点3.1
(1) 在DEBUG中,用 "D 0:0 lf" 查看内存,结果如下:
0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88
下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值
程序分析:
【1】首先确定ds值是0001H,如果偏移地址是0000H的话,它们物理地址是00010H;那么如果它的段地址是0000H(因为此时段地址是0000H)的情况下,它的偏移地址是从0010H开始的。因为它们的物理地址是唯一的,而且是同一个。
【2】经过上述分析后,我们确定ds:[0000]是指的0000:0010开始的内存单元(也就是debug第二行内存单元开始)。
【3】注意CPU访问内存单元时,指令的操作对象决定了内存单元是字节型单元还是字型单元。
【4】debug中,内存单元从左到右是地址从低到高顺序排列的。
【5】add是不带进位的加法,如果遇到进位,那么进位值被截断(舍去)。但它影响标志位。
【6】al、ah和ax是3个不同的寄存器,al存放运算结果产生的进位不会存放到ah中,虽然ah是高8位的8位寄存器。
结果如下:
mov ax,1
mov ds,ax
mov ax,[0000] ax= 2662H
mov bx,[0001] bx= E626H
mov ax,bx ax= E626H
mov ax,[0000] ax= 2662H
mov bx,[0002] bx= D6E6H
add ax,bx ax= FD48H
add ax,[0004] ax= 2C14H ;2ECCH+ FD48H=1 2C14H,其中进位截断。
mov ax,0 ax= 0
mov al,[0002] ax= 00e6H
mov bx,0 bx= 0
mov bl,[000c] bx= 0026H
add al,bl ax= 000CH ;同理:E6H+26H=1 0CH,其中进位截断
(2) 内存中的情况如图3.6所示
各寄存器的初始值:cs=2000h,ip=0,ds=1000h,ax=0,bx=0;
程序分析:
【1】CPU总是从cs:ip指向的内存单元读取指令并运行。故先从mov ax,6622H读取并执行。
cs=2000H;ip=0003H; ds=1000H ;ax=6622H;bx=0000H
【2】执行jmp指令(段间直接跳转),确定0ff0:0100的物理地址是:0ff0*10H+100H=10000H;故CPU从物理地址是10000H开始处读取并执行代码。正好在10000H单元开始有指令:mov ax,2000H。这也证明了物理地址是唯一的,基础地址+偏移地址的组合是多种的。
cs=0ff0H;ip=0103H;ds=1000H;ax=2000H;bx=0000H
【3】开始执行下一个指令:mov ds,ax;
cs=0ff0H;ip=0105H;ds=2000H;ax=2000H;bx=0000H
【4】执行下一个指令:mov ax,[0008],由于ds指向了2000H段内存,[0008]代表了字型单元,值为C389H
cs=0ff0H;ip=0108H;ds=2000H;ax=C389H;bx=0000H
【5】执行下一个指令:mov ax,[0002],由于ds指向了2000H段内存,[0002]代表了字型单元,值为EA66H
cs=0ff0H;ip=010BH;ds=2000H;ax= EA66H;bx=0000H
答案:
【1】CPU执行序列为:
mov ax,6622H
jmp 0ff0:0100
mov ax,2000H
mov ds,ax
mov ax,[0008]
mov ax,[0002]
【2】CPU执行每条指令后,cs、ip和相关寄存器的值:
mov ax,6622H
cs=2000H;ip=0003H; ds=1000H ;ax=6622H;bx=0000H
jmp 0ff0:0100
cs=0ff0H;ip=0100H;ds=1000H;ax=6622H;bx=0000H
mov ax,2000H
cs=0ff0H;ip=0103H;ds=1000H;ax=2000H;bx=0000H
mov ds,ax
cs=0ff0H;ip=0105H;ds=2000H;ax=2000H;bx=0000H
mov ax,[0008]
cs=0ff0H;ip=0108H;ds=2000H;ax=C389H;bx=0000H
mov ax,[0002]
cs=0ff0H;ip=010BH;ds=2000H;ax=EA66H;bx=0000H
【3】再次体会,数据和指令(数据和程序)在内存中存储是没有区别的,是数据还是指令?需要看它具体的应用体现。如果cs:ip指向的内存单元,那么它就作为CPU指令读取并执行。
程序分析:
【1】首先我们观察这二段连续内存,都是8个字,程序中已经给出了ds指向了1000H段的内存单元。
【2】那么我们可以通过将20000H开始的内存段定义为一个堆栈段,长度是10H,使用push操作将1000H数据段数据逆序复制到我们定义的ss段中。
【3】注意体会push指令的压栈操作。这程序是使用push指令复制数据
代码完成如下:
mov ax,1000H
mov ds,ax
mov ax,2000H ;由于ss是段寄存器,必须间接赋值。
mov ss,ax ;使ss栈顶指向2000H段内存
mov sp,10H ;初始化栈顶指针,栈空状态,向低地址发展
push [0]
push [2]
push [4]
push [6]
push [8]
push [A]
push [C]
push [E]
(2)补全下面的程序,使其可以将10000H-1000FH中的8个字,逆序拷贝到20000H-2000FH中。
程序分析:这个程序是通过pop指令在内存中复制数据的。同上述基本差不多。
mov ax,2000H
mov ds,ax
mov ax,1000H
mov ss,ax ;使ss栈顶指向1000H段内存
mov sp,0 ;初始化栈顶指针,由于栈结构满了,sp=0,向高地址发展
pop [e]
pop [c]
pop [a]
pop [8]
pop [6]
pop [4]
pop [2]
pop [0]