(1)将下面的程序保存为 t1.asm 文件,将其生成可执行文件 t1.exe。
assume cs:codesg
codesg segment
mov ax,2000H
mov ss,ax
mov sp,0
add sp,10
pop ax
pop bx
push ax
push bx
pop ax
pop bx
mov ax,4c00H
int 21H
codesg ends
end
第一步: 使用 masm 将 t1.asm 编译成 t1.obj 文件。
第二步: 使用 link 将 t1.obj 文件连接生成可执行文件 t1.exe。
(2)用 Debug 跟踪 t1.exe 的执行过程,写出每一步执行后,相关寄存器中的内容和栈顶的内容。
初始时,各寄存器的内容:
执行 mov ax,2000H 后各寄存器的内容:
执行 mov ss,ax mov sp,0 后各寄存器的内容(设置SS段寄存器的下一条命令会自动执行):
执行 add sp,10 后各寄存器的内容:
执行 pop ax 后各寄存器的内容:
执行 pop bx 后各寄存器的内容:
执行 push ax 后各寄存器的内容:
执行 push bx 后各寄存器的内容:
执行 pop ax 后各寄存器的内容:
执行 pop bx 后各寄存器的内容:
(3)PSP 的头两个字节是 CD 20,用 Debug 加载 t1.exe,查看 PSP 的内容。
从下图可以看出 PSP 以 CD 20 开头的内存中内容。
为啥上图中,查看的内存起始地址是 ds:0, 而非 cs:ip 呢?
因为在DOS系统中,exe文件被加载进内存后的位置结构图如下所示。
首先找到一段容量足够的空闲内存区 SA:0,并将该内存区的段地址存入 DS 寄存器中;
然后在此内存区的前 256 个字节中,创建一个称为程序段前缀(PSP)的数据区,DOS要利用PSP来和被加载程序进行通信;
最后,再将待执行程序加载进内存地址 SA + 10H:0 开始的空间中。