汇编程序的运行方法

汇编程序的运行方法,第1张

汇编语言源程序运行方法:

1、找到一段起始地址为sa:0000(即起始地址的偏移地址为0)的容量足够的空闲内存区。

2、在这段内存区的前256个字节中,创建一个称为程序段前缀(psp)的数据区,dos利用psp来和被加载程序进行通信。

3、从这段内存区的256字节处开始(在psp的后面),将程序装入,程序的地址被设为sa+10h:0;空闲内存区从sa:0开始,0~255字节为psp,从256字节处开始存放程序,为更好地区分psp和程序,dos将划分到不同的段中,如下这样的地址安排:

空闲内存区:sa:0

psp区:sa:0

程序区:sa+10h:0

注意:psp区和程序区虽然物理地址连续,却有不同的段地址。

4、将该内存区的段地址(sa)存入ds中,初始化其它相关寄存器后,设置cs:ip指向程序的入口(sa+10h:0)。

第一段程序:

CLI

CLD

MOV AX,0 //这里,为什么要赋0呢?

MOV ES,AX //为什么要通过AX才能传到ES

说明:

因为实模式下中断向量表是在0000:0000处开始的,所以要将目标位置的段地址设为0。与段寄存器有关的数据传送等指令不允许立即数作为另一个 *** 作数,所以要借助AX等通用寄存器。

MOV DI,4*60H //这个是中断向量指针

MOV AX,OFFSET_INTR //然后把偏移值传到AX

STOSW //这里就很有问题了,书上的话是"AX->[DI][DI+1],然后DI+2"莫名

咧,首先是为什么STOSW是个什么东西,然后上面的DI+1是指连续四个

存储单元中从下往上的第二个单元吗?然后,DI+2,是在什么条件下发

生的?

说明:

STOSW指令会将AX的内容存储到ES:[DI]处开始的两个字节里(AL在低地址的字节即ES:[DI]中、AH放到高地址的字节即ES:[DI+1]处,完成后自动将DI加2以指向下一次的目的地址。这部分和书上的意思是完全一致的,这里只是用自然语言描述了一下。

你所说的该中断向量的连续四个字节[DI]、[DI+1]、[DI+2]、[DI+3]中,[DI]和[DI+1]中的字是中断入口地址的偏移量部分,[DI+2]、[DI+3]是中断入口地址的段地址部分。假设某中断服务程序的入口地址是 FFF0:1234,那么[DI]、[DI+1]、[DI+2]、[DI+3]分别就应该是 34h, 12h, f0h, ffh。你此处提问的后半部分我没太明白,希望前面的解释能有帮助。

MOV AX,SEG_INTR

STOSW

STI

第二段程序:

MOV AX,00H

MOV ES,AX

MOV BX,60H*4 //这里好像是把内存四个连续单元的第一个地址赋值给BX

MOV AX,006DH //006DH是偏移地址

MOV ES:[BX],AX //好讨厌额,这里又不懂了,书上说是"装入偏移地址",

可是MOV BX,60H*4感觉好像是已经装好了(#‘′)。。。

说明:

CS:006D是真正的中断处理程序的入口地址,这段程序是要将这个地址填写到中断向量表中 60H 中断的表项里。由于每个中断向量要占4个字节(分别存放对应的中断处理程序的入口地址的偏移/段地址),因此第60H号中断向量在表中的位置(注意不是中断处理程序的入口地址)就是0000:60H*4到0000:60H*4+3处的4个字节,程序把60H*4这个起始字节的偏移量放在BX里,ES放的是0段,AX放的则是要填入表中的真正的中断处理程序的入口地址,CS是这段代码的段地址(因为这个程序提供的60H中断处理程序也是在这个代码段里)然后依次填入。

PUSH CS

POP AX //这里书上说是"获取中断服务程序的段基址"我就觉得不懂,照说这段基址怎么会和CS有关系呢

MOV ES:[BX+2],AX

说明:

PUSH CS/POP AX是以前8086汇编里很常用的替代MOV AX,CS的办法(好像是比MOV AX,CS少用一个指令周期,能少许快点),其作用就是MOV AX,CS。这段程序是要把60H中断向量指向自己的中断处理程序(位于CS:006D处),这个中断处理程序是和这里的初始化代码从同一个段计算偏移的、段地址也相同,所以直接用执行到此初始化代码时的CS填写中断向量的段地址即可。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11537729.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存