汇编语言复习摘要六——包含多个段的程序

1. 先考虑这样一个问题:计算以下8个数据的和,结果存放在寄存器ax中:

0123h 0456h 0789h 0abch 0defh 0fedh 0cbah 0987h

毫无疑问,要累加这些数据,就必须把这些数据先存放在内存单元中,然后循环读取每一个数据,进行累加。从何找到这段连续的内容单元?一般来说,我们无法自己决定使用哪段内存空间,所以把这个任务交给操作系统自己来决定:

 

代码
assume cs:code
code segment
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
 
mov bx, 0
mov ax, 0
mov cx, 8
s:
add ax, cs:[bx]
add bx, 2
loop s

mov ax, 4c00h
int 21h
code ends
end

在上面的例子中,dw的意思是“define word”,即定义了已连串的字型数据(后面8个数据)。程序从哪里开始执行?从CS:IP指向的地方开始执行。然而这里,CS:IP指向的第一条指令是dw开始的定义,而我们希望是直接从mov bx, 0;这句开始执行,这样有可能造成执行出现了问题。如何解决?

 

1)可以在debug下,直接设置CS:IP,让IP指向mov bx, 0;也就是修改IP的值为:0010h;

2)告诉CPU从哪里开始执行我们的代码,即把程序修改为:

 

代码
assume cs:code
code segment
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
start:
mov bx, 0
mov ax, 0
mov cx, 8
s:
add ax, cs:[bx]
add bx, 2
loop s

mov ax, 4c00h
int 21h
code ends
end start

 

添加了:"start"和"end start"。start是一个标号,end start告诉CPU程序的入口是哪里。所以,end还有指明程序入口点的作用。在编译、链接之后,由“end start”指明的程序入口被转化为一个入口地址,存储在可执行文件的描述信息中。显然,这种做法比第一种做法现实得多。

 

2. 将数据、代码、栈放入不同的段:把这些内容全部放在代码段中无疑会让程序显得混乱而且难以管理和操作,容易出错,所以,要把数据、代码和栈放入不同的段中,这也体现了软件工程中“分而治之”的思想。

 

代码
assume cs:code, ds:data, ss:stack
data segment
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
data ends

stack segmetn
dw
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
stack ends

code segment
start:
mov ax, stack
mov ss, ax
mov sp, 20h

mov ax, data
mov ds, ax

mov bx, 0
mov cx, 8
s:
push [bx]
add bx, 2
loop s

mov bx, 0
mov cx, 8
s0:
pop [bx]
add bx, 2
loop s0

mov ax, 4c00h
int 21h
code ends
end start

1)定义多个段的方法:定义数据段和栈段跟定义代码段一样,都是:XXX segment ; XXX ends;

2)对段地址的引用:如何访问到段的开始地址,寻址是按照:段地址×16 + 偏移地址来实现的。每一个段的标号就是表示段地址,比如:data segment;中data就是数据段的段地址。

mov ax, data

mov ds, data

就是使ds指向了data段中的第一个单元,那么以后:mov [0], ax; 就是把ax的内容送入到data段开始的第一个内存单元;

但是,我们不能这样写:mov ds, data; data其实是一个段地址,一个值,这样写相当于把值直接送入ds,这是不允许的。

3)要注意,所谓的数据段,代码段,栈段都是我们自己定义的,是为了方便程序员阅读的,CPU并不知道哪些就是数据段,哪些是代码段,哪些是栈段。所以,data, code, stack只是一系列的标号而已,标号就是为了提高可读性。

assume cs:code, ds:data, ss:stack;这句只是将你定义的具有一定用途的段和相关的寄存器联系起来,并不是说,CPU知道cs指向了code, ds指向了data,ss指向了stack;所以,我们仍然需要在程序中写:

mov ax, stack

mov ss, ax

mov sp, 20h

这样类似的指令来指明ss指向了stack。所以,code, data, stack完全可以换成其他名字,只是我们在定义的时候需要定义一个可读性比较强的标号。

posted @ 2010-09-25 21:41  Linjian  阅读(781)  评论(0编辑  收藏  举报