数据段data segment 堆栈段stack segment 代码段code segment的 段地址 有什么关系?系统是怎么分配 数据段 堆栈段 代码段 的段地址的,他们是连续相接的吗?只剩下10个财富 了sorry!系统是怎么分配 数据
来源:学生作业帮助网 编辑:六六作业网 时间:2024/12/23 22:32:25
数据段data segment 堆栈段stack segment 代码段code segment的 段地址 有什么关系?系统是怎么分配 数据段 堆栈段 代码段 的段地址的,他们是连续相接的吗?只剩下10个财富 了sorry!系统是怎么分配 数据
数据段data segment 堆栈段stack segment 代码段code segment的 段地址 有什么关系?
系统是怎么分配 数据段 堆栈段 代码段 的段地址的,他们是连续相接的吗?
只剩下10个财富 了sorry!
系统是怎么分配 数据段 堆栈段 代码段 的段地址的,他们对应的内存单元段 是连续相接的吗?
assume cs:code,ds:data,ss:stack
data segment
dw 0,1,2,3,4,5
data ends
stack segment
dw 0,2,3,4,5,6
stack ends
code segment
start:
mov ax,[0]
add ax,[2]
add ax,[ 4]
add ax,[6]
push ax
code ends
end start
数据段data segment 堆栈段stack segment 代码段code segment的 段地址 有什么关系?系统是怎么分配 数据段 堆栈段 代码段 的段地址的,他们是连续相接的吗?只剩下10个财富 了sorry!系统是怎么分配 数据
对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段.我们可以将一组长度为N(N less or equal to 64KB)、地址连续、起始地址为16的倍数的内存单元作专门存储数据的内在空间,从而定义了一个数据段.比如用123B0H -- 123B9H这段内存空间来存放数据,我们就可以认为,123B0H -- 123B9H这段内存是一个数据段,它的段地址为123B0H,长度为10个字节.
如何访问数据段中的数据呢?将一段内存当作数据段,是我们在编程时的一种安排,可以在具体操作的时候,用DS存放数据段的地址,再根据需要,用相关指令访问数据段中的具体单元.
比如,将123B0H -- 123B9H 的内存单元定义为数据段.现在要累加这个数据段中的前3个单元的数据,代码如下.
mov ax,123BH
mov ds,ax ; 将123BH送入ds中,作为数据段的段地址
mov al,0 ; 用al 存放累加结果
add al,[0] ; 将数据段第一个单元(偏移地址为0)中的数值加到al中
add al ,[1] ; 将数据段第二个单元(偏移地址为1)中的数值加到al中
add al,[2] ; 将数据段第三个单元(偏移地址为2)中的数值加到al中.
栈 :栈是一种具有特殊访问方式的存储空间.它的特殊性在于,最后进入这个空间的数据,最先出去.
8086 CPU 提供相关的指令来以栈的方式访问内存空间,这意味着,在基于8086 编程的时候,可以将一段内存当作栈来使用.
8086 CPU 提供入栈和出栈指令,最基本的两个是 PUSH(入栈) 和 POP (出栈).比如 ,push ax 表示将寄存器ax 中的数据送入栈中,pop ax 表示从栈顶取出数据送入ax.8086 CPU 的入栈和出栈操作都是以字为单位进行的.
下面举例说明,我们可以将 10000H -- 1000FH 这段内存当作栈来使用.
mov ax,0123H
push ax
mov bx,226H
push bx
mov cx,1122H
push cx
pop ax
pop bx
pop cx
这里有两个问题.
其一,我们将10000H - - 1000FH 这段内存当作栈来使用,CPU执行push 和 pop 指令时,将对这段空间按照栈的后进先出的规则进行访问.但是,一个重要的问题是,CPU如何知道 10000H -- 1000FH 这段空间被当作栈使用?
其二,push ax 等入栈指令执行时,要将寄存器中的内容放放当前栈顶单元的上方,成为新的栈顶元素;pop ax 等指令执行,要从栈顶单元取出数据,送入寄存器中.显然 push,pop 在执行的时候,必须知道哪个单元是栈顶单元,可是,如何知道呢?
8086 CPU 中,有两个寄存器,段寄存器 SS 和寄存器 SP,栈顶的段地址存在SS中,偏移地址存放在SP中,任意时刻,SS:SP指向栈顶元素.push 指令和pop指令执行时,CPU从SS和SP中得到栈顶的址址.
现在,我们可以完整的描述 push 和 pop 指令的功能了,例如 push ax.
push ax 的执行,由以下两步完成.
1.SP = SP -2,SS:SP 指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
2.将ax 中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶.
在masm中有一条重要的伪指令 assume ,下面给出 ASSUME 的具体用法
Setting the ASSUME Directive for Segment Registers
Many of the assebler instructions assume a default segment.For example,
JMP assumes the segment associated with the CS register,PUSH and POP assume
the segment associated with the SS register,and MOV instructions assumes the segments
associated with the DS register.
When the assebler needs to reference an address,it must know what segment contains the address.It finds this by using the default segment of group addresses assigned with the
ASSUME directive.The syntax is :
ASSUME segresister :seglocation [,segregister :seglocation ]
ASSUME dataregister; qualifiedtype [,dataregister :qualifiedtype]
ASSUME [regiser:] NOTHING [,register :NOTHING]
ASSUME register :FLAT [,register :FLAT ]
The ASSUME directive can define a segment for each of the segment registers.the
segregister can be CS,DS,ES,or SS ( and FS and GS on the 80386/486).
段寻址伪指令 ASSUME
格式 :ASSUME [段寄存器]:[ 段名],[段寄存器]:[段名],...
功能 :用于告知汇编程序,段寄存器CS、DS 、ES 和SS 的内容将被设定为那些段或组的段址.所以 代码段,数据段,堆栈段的 地址是 可 以人为设置的.
在机器刚开机时,堆栈是还没有建立起来的,此时是不能用栈的.