实验任务:

(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

 

步骤:

1、进入dos,打开edit 

注意,本实验用的是dosbox系统,但是这个系统操作其实比较繁琐,以后实验操作熟练度上升,可以使用masm集成实验环境。

-----------------------------------------------------------------------------------------------------

2、输入代码,如图:

注意倒数第二行的“ends”和最后一行的“end”不要写错。

-------------------------------------------------------------------------------------------------------------------------------------

3、保存文件

截图:

因为笔者之前设置过默认保存路径,因此保存时不必选择路径。

注意:文件扩展名为.asm

--------------------------------------------------------------------------------------

4、编译

①进入dos,进入d:\masm(保存路径为d:\masm\1.asm),运行masm.exe

②在文件源后面(source filename 【.ASM】)后面直接输入文件名即可,如本实验的1.asm即可,不必详细输入文件路径

③【1.boj】文件名默认为1.boj,不必另行指定文件名,直接enter跳过

④source listing 编译程序提示输入列表文件的名称,enter跳过即可

⑤corss-reference 编译程序提示出入交叉引用文件的名称,enter跳过即可

⑥忽略交叉引用文件的生成后,屏幕显示如图:

通过对1.asm的编译,masm目录下生产了新文件1.boj。当然,这是在没有出现错误的情况下。错误大概有两类:1、程序中有“Service Erroes”;2、找不到所给出的源程序文件

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5、连接

①进入dos方式,进入d:\masm,运行link.exe 

输入:d:\link 1(连接1.obj)

注意:输入d:\masm\link 无效,d:\masm\link 1也无效

------------------------------------------------------------------

②run file生成文件,程序默认输出可执行文件1.exe,enter跳过指定命名,生成1.exe

------------------------------------------

③list file:连接程序提示输入映像文件,enter跳过即可

---------------------------------------------------------------------------------------

④ libraries 连接程序提示输入库文件的名称,enter跳过即可

--------------------------------------------------------------------------------------

⑤忽略库文件的连接后,屏幕显示如图:

警告错误“没有栈段”,这里不必理会

------------------------------------------------------------------------------------------

【2】用debug跟踪t1.exe的执行过程

①在命令提示符下输入:debug 1.exe

②用r查看寄存器信息:

d cs:0

u cs:0

 

 ③执行代码:

mov ax,2000

mov ss,ax

mov sp,0

解释:将2000H段开始的内存单元创建一个栈结构。栈顶指针ss:sp指向00H   如图:

——————————————————————————————————————————————————————————————

add sp,10

解释:使sp指向10h,即栈结构分配空间为10个字节,如图:

 ——————————————————————————————————————————————————————————————

pop ax                               -------------------------->弹出栈顶元素赋给ax;sp=sp+2=000A+2=000CH

pop bx                               -------------------------->弹出栈顶元素赋给bx;sp=sp+2=000C+2=000EH

 注意:此时栈顶为000E,已经越界,触发中断机制  如图:

 

 ———————————————————————————————————————————————————————————————

push ax                              -------------------------->将ax压入栈中;sp=sp-2=000EH-2=000CH

push bx                              -------------------------->将bx压入栈中;sp=sp-2=000CH-2=000AH

 

 

 ————————————————————————————————————————————————————————————————————

pop ax                                -------------------------->弹出栈顶元素赋给ax;sp=sp+2=000A+2=000CH

pop bx                                -------------------------->弹出栈顶元素赋给ax;sp=sp+2=000A+2=000EH

 

 

总结:在这个栈结构中,栈内存没有使用,可以随意越界,但是如果栈内有数据,越界将会破坏数据,因此一定要注意栈的空间分配

 

 (3)PSP的头两个字节是CD 20,用debug加载t1.exe,查看PSP的内容。

书上p92提到:PSP存放在ds:0的前256个字节中,从ds中可以得到PSP的段地址SA,PSP的偏移地址为0.则物理地址为SA*16+0,因为PSP占256(100h)个字节,所以程序的物理地址为 SA*16+0+256=SA*16+16+16+0=(SA+16)*16+0

可用段地址和偏移地址表示为SA+10H:0,即cs=ds+10h(如ds=129E,cs=12AE)

 

 

posted on 2018-10-28 15:20  Bitterandsweet  阅读(569)  评论(1)    收藏  举报