将数据、代码、栈放到不同的段(感觉很好)
时间:2014-05-01 18:14:07
收藏:0
阅读:368
1.将数据、栈都放到代码段中太混乱了。下面我们写一个程序,将数据、代码、栈放到不同的段中
assume cs:code,ds:data,ss:stack data segment dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H data ends stack segment dw 0,0,0,0,0,0,0,0 stack ends code segment start: mov ax,stack mov ss,ax mov sp,16 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)现在,程序中有多个段,我们如何访问段中的数据呢?当然要通过地址,而地址是分为两部分的,即段地址和偏移地址。我们如何指明要访问的数据的段地址呢?在程序中,段名就相当于一个标号,它代表段地址。所以指令”mov ax,data"的含义就是将名称为“data"的段的段地址送入ax。一个段中的数据的段地址可以由段名代表,偏移地址就要看它在段中的位置了。程序中”data“中的数据0abch的地址就是data:6。
(2)代码段、数据段、栈段完全是我们的安排
现在,我们以一个具体的程序来再次讨论一下所谓的代码段、数据段、栈段。在汇编程序中,我们可以定义很多的段,比如上面我们定义三个段“code”,“data",“stack”。我们可以安排他们存放代码段、数据、栈。那么我们如何让CPU按照我们的这种安排来执行这个程序呢?我们来看看源程序中对这三个段所做的处理:
- 我们在源程序中为这三个段起了具有含义的名称,数据段命名data,代码段命名code,栈空间命名stack。这样命名之后,CPU是否就去执行code段中的内容,处理data段中的数据,将stack当做栈了呢?当然不是,我们这样命名,仅仅是为了我们程序便于阅读,这些名称同start、s、s0等标号一样,仅在源程序中存在,CPU并不知道他们。
- 我们在程序中使用伪指令assume cs:code,ds:data,ss:stack将cs、ds和ss分别和code、data、stack段相连,这样做之后,CPU是否就将cs指向code,ds指向data,ss指向stack,从而按照我们的意图来处理这些段呢?当然也不是,要知道assume是伪指令,是由编译器执行的,也是仅在源程序中存在的信息,CPU并不知道他们。我们不必探究assume的作用,只要知道需要用它将你定义的具有一定用途的段和相关寄存器联系起来就可以了。
- 若要CPU按照我们安排行事,就要用机器指令控制它,源程序中的汇编指令是CPU要执行的内容。CPU如何知道去执行他们?我们在源程序的最后用end start 说明了程序的入口,这个入口将被写入可执行文件的描述信息,可执行文件被加载入内存之后,CPU的CS:IP被设置指向这个入口,从而开始执行程序中的第一条指令。标号start在code段中,这样CPU就将code段中的内容当做指令来执行。我们在code段中,使用指令:
mov ax,stack mov ss,ax mov sp,16
设置ss指向stack,设置ss:sp指向stack:16,CPU执行这些指令后,将把stack段当做栈空间来用。CPU若要访问data段中的数据,则可用ds指向data段,用其他的寄存器来存放data段中数据的偏移地址。 - 总之,CPU到底如何处理我们定义的段中的内容,是当做指令执行,当做数据访问,还是当做栈空间,完全是靠程序中的具体汇编指令,和汇编指令对CS:IP,SS:SP,DS等寄存器的设置来决定的。
评论(0)