小弟写了这样一个汇编程序:
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
编译链接后形成exe,然后再命令行下用debug,单步调试。发现每次一开始这几个寄存器的值是不变的:
如图:

其中CX保存的是源程序中汇编之类的长度;DS和ES的值相等,保存的是PSP(程序段前缀)的段地址;CS和SS的值相等,保存的是代码段和堆栈段的段地址。我们知道PSP占100H个字节,其后紧跟的是代码段。PSP从DS:0开始到(DS+10H):0(也就是CS:0)。
我的疑问是:为什么PSP的段地址总是不变,也就是说为什么这个程序总会被加载到CS:0这个单元开始的内存块?
谢谢!!
------解决思路----------------------
这个地址是系统分配的,找块空内存把程序往那里一放就结了!
就向我的机器,如果不指定,ds段都是075a开始
------解决思路----------------------
程序段前缀(PSP)简言之就是1个数据结构,它和用户程序本身位于同一内存分配块中,构成一个不可分割的整体。它是DOS(作为加载程序的父程)和被加载程序的软件接口。它主要是用来存放与用户程序有关的一些控制信息,并提供程序正常或异常结束时返回DOS的途径。它总共有256个字节长,位于程序所在段的起始位置。

------解决思路----------------------
因为 dos 是单一执行模式的,运行你的程序,退出了,再次运行,内存和第一次运行时的状态一样,所以当然就加载在还是原来的位置了;dos 的内存分配策略就是从可用内存串表里找寻到第一个满足大小的内存块来使用,不是你说的随便找个地方就可以。或者,你找个 ucdos 里的 clock 或 ascii 驻留类软件来,先运行你的程序,在运行下 clock ,然后再次运行你的程序,看看两次自己的程序的 ds 还能一样了!
------解决思路----------------------
DOS PSP就是在程序开始的位置0的位置,程序从100H开始执行,PSP正好100H(256)字节。
格式,请看3楼,版主给出的格式。
程序初始化为CS=SS,DS=ES
需要设置的,在程序,开头设置DS,ES,SS,
CS不用设置;
用调用指令或者跳转指令,就可以改变CS了。