汇编语言(王爽第三版)实验3 编程、编译、连接、跟踪
(2017-05-13 17:06:57)
标签:
汇编王爽it教育 |
分类: 汇编语言(王爽第三版)实验 |
实验3 编程、编译、连接、跟踪
(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
(2)用debug跟踪t1.exe的执行过程,写出每一步骤执行后,相关寄存器中的内容和栈顶的内容。
(3)PSP的头两个字节是CD 20,用debug加载t1.exe,查看PSP的内容。
实验结果:
【1】编译、连接t1.asm汇编源程序。
1)在windows XP中,打开cmd窗口,编译t1.asm程序。如下图:
E:\assembly>masm t1.asm
Microsoft (R) MASM Compatibility Driver
Copyright (C) Microsoft Corp
1993.
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp
1981-2000.
如果没有任何错误,编译器会生成一个t1.obj的文件。
如果有语法等严重的错误,编译器会给出错误信息,你可以根据错误信息,修改源代码相关的行。
连接这个obj文件,并生成t1.exe文件:如下图:
E:\assembly>link t1.obj
Microsoft (R) Segmented
Executable Linker
Copyright (C) Microsoft Corp
1984-1993.
Run File [t1.exe]: t1.exe
List File [nul.map]:
Libraries [.lib]:
Definitions File [nul.def]:
LINK : warning L4021: no stack segment
LINK : warning L4038: program has no starting address
连接讲解:
1)其中运行文件:我们输入我们将要生成的可执行程序(例如.exe)文件的名称。
List File [nul.map]: 我们回车,没有列表文件;
Libraries [.lib]: 我们回车,没有库文件
Definitions File [nul.def]: 我们回车,没有交叉定义文件
2)LINK : warning L4021: no stack segment
关于编译器的详细介绍,请参考相应的编译器手册。
【2】用debug跟踪t1.exe的执行过程
在命令提示符下键入:debug t1.exe
使用r命令查看寄存器信息。
-r
AX=0000
DS=0B55
0B65:0000
B80020
1)CX寄存器介绍:
cx=0016; 含义:cx寄存器是通用寄存器,也是计数寄存器,cx还有一个功能是在程序最初始记录程序代码的字节数;我们使用d命令查看它
-d cs:0
0B65:0000
0B65:0010
红色标记的是执行的机器码。注意此时的0016是16进制的,也就是22个字节,你数数!
你也可以使用U命令查看汇编指令和机器码,一样。
-u cs:0
0B65:0000
B80020
0B65:0003
8ED0
0B65:0005
BC0000
0B65:0008
83C40A
0B65:000B
58
0B65:000C
5B
0B65:000D
50
0B65:000E
53
0B65:000F
58
0B65:0010
5B
0B65:0011
B8004C
0B65:0014
CD21
各寄存器状态值:CS=0B65
2)执行代码
代码含义:将2000H段开始的内存单元创建一个栈结构。栈顶指针ss:sp指向00H。
这就意味着如果栈结构是空的,那么它的栈容量是64K。
怎么没有了那些t命令的中断例程保存的寄存器变量了?你在1FFF:0010H处,也就是它的低地址处看看有吗?
执行后:
AX=2000
DS=0B55
3)执行代码:
代码含义:明确说明sp指向10,也就是说我们创建的栈结构空间分配是10个字节;
执行后:
AX=2000
DS=0B55
4)执行代码:
代码含义:pop ax;将ss:sp指向的字单元赋值给ax=00;sp=sp+2=000A+2=000CH;
-d ss:0
2000:0000
执行后:
AX=0000
DS=0B55
使用d查看栈段内存:
-d ss:0
2000:0000
我们发现sp=000EH,也就是栈底向高地址发展了,栈结构占用的内存空间也变大了。
5)执行代码:
代码含义:push ax;首先sp=sp-2=000EH-2=000CH;然后将ax值压栈,此时ax=00,
执行后:
AX=0000
DS=0B55
使用d查看栈段内存:
-d ss:0
2000:0000
内存中红色标记的部分就是压栈的2个字单元。
6)执行代码:
代码含义:pop ax;首先将ss:sp指向的内存字单元赋值给ax,也就是2000:000aH指向的字单元(00 00);然后sp=sp+2=000AH+2=000CH;
执行后:
AX=0000
DS=0B55
使用d查看栈段内存:
-d ss:0
2000:0000
总结:
我们使用栈时要小心,这个例子,栈结构的内存是没有使用的,它的栈顶随意的超界,没有事情,如果有数据的话,就破坏程序了。
(3)PSP的头两个字节是CD 20,用debug加载t1.exe,查看PSP的内容。
-d ds:0
0B55:0000
0B55:0010
0B55:0020
0B55:0030
0B55:0040
0B55:0050
0B55:0060
0B55:0070