问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

数据段data segment 堆栈段stack segment 代码段code segment的 段地址 有什么关系?

发布网友 发布时间:2022-05-02 21:08

我来回答

1个回答

热心网友 时间:2023-10-09 13:05

对于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 的内容将被设定为那些段或组的段址。 所以 代码段,数据段,堆栈段的 地址是 可 以人为设置的。

在机器刚开机时,堆栈是还没有建立起来的,此时是不能用栈的。追问非常感谢你的回答,还有下面一个问题:
像这样一个程序

像这样一个程序,我们让cpu执行这个程序,它会先把程序加载到内存中,程序加载到内存,系统会给这个程序分配data 段 stack 段 code 段来存储这个程序,这里存储程序的时候,系统怎么分配data段和stack段 和code段的内存空间来存储不同的段?cs ds ss它们有 什么关系?系统根据什么规则来分配cs ds ss 的?

追答

你这里的系统是指os么? 要知道legacy bios 是全部用汇编语言写的,在它引导os之前,是不存在os这个概念的,所以并不是系统分配的,从你按下power button, 计算机的上电时序完全是人为控制的(可以用CPLD),当所有的电都 standby了,南桥发一个platform ret 信号给cpu,此时CPU去执行第一条指令,这个时候,所有的chipset,memory都还没有完成初始化,也就是说,是还不能用的,所以i386就人为的规定第一条指令放在哪里,这条指令是放在bios firmware下面的,下图是haswell-ep 处理器的基本架构。

CPU 并不care第一条指令入在哪里,它只管扔出这个地址,谁拥有这个地址,谁就做出响应,然后BIOS开始做事情,它要打一些microcode, 注意些时内存还不能用,BIOS是rom,很多指令是不能执行的,比如call,此时它会把BSP(现在都是多处理器结构,BSP初始化完成之后,去下指令初始化别的CPU,叫AP)的L2 cache作为临时ram.然后去初始化内存,load 各种option rom,最后去引导os,在这一段时间,计算机做的每一步都是人为控制的,所以并不存在系统来分配这个概念,你所说的段,仅仅是一段连续的内存(逻辑上的),然后你指定一个寄存器去放段的起始地址(给编译器看的),比如:  下面代码的mov ds,ax

assume cs:code

data  segment

  db   'Welcome to masm!', 0

data ends

 

code segment

   start: mov  dh, 8

            mov  dl, 3

            mov  cl, 2

            mov ax, data       

            mov  ds, ax   ; 此时ds 指向了data段,  完成了ds 的赋值

            mov bx, 0     ; ds: bx 指向data 段中的第一个单元.

 

学计算机 ,就要把它学透,从power on,到 application的执行。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...分?普通话不好没事吧?我现在东营工作,这边有没有短期的培训... “腾马培训”的公务员面试辅导有实战模拟吗? 北京腾马顺通物流有限公司是骗人的吗?在木樨园那一带 vivonex屏幕是多大的 vivoNEX配置是怎么样的 衣服被染色了怎么能恢复? 描写关于旅行的唯美句子 关于旅行的文艺句子 旅行简短文艺句子出去玩的心情发朋友圈 麻辣捞面怎么做? 南京市有哪些私立高中 参加中国风全国中小学创意作品展评活动获奖后中考可以加分吗 从艺术表现的角度评价《开国大典》这幅画的作品 汇编程序解释,完整解释哦 求大神,汇编语言,帮忙解释一下每条语句,主要是前半部分 code segment a iPad给素描图上色用什么软件适合新手? 请教各位高人 要想画成连环画内样是得先去学素描还是学国画?我是说三国演义内样的中国风的连环画? 开国大典的作者是谁? 80X86汇编中, CS, C是code的简写, 那S是section的简写还是segment的简写? 从市场买回来的口蘑,炒菜前是整个焯水还是切片再焯水呢? 开国大典的作者 从市场买回来的口蘑,炒菜前是整个焯水还是切片再焯水呢 这段代码什么意思啊?麻烦给解释一下 CODE SEGMENT ASSUME CS:CODE BEGIN:MOV AH,1;从键盘输入一个数据 IN 新鲜口蘑不焯水可以吗 请问这段汇编语言每句话的意思 《开国大典》的作者资料 我想画漫画但是不怎么会画画,同时家里没钱去读美术科,要怎么办? java中 stack segment 、heap segment、code segment 、data segment ; 4岁小孩身高增长缓慢怎么办 小孩个子长得慢是什么问题,吃什么可以改善 素描的脖子怎么画? 中国风韩智平板 什么是段寄存器? 求微机原理程序注释 如何下载谷歌浏览器官方版,离线安装的版本,也就是说,突破长城牌防火墙下载正宗官方版本 为什么安装google安装不了 一句SQL导入数据的语句,想问一下,专业人士进~跪谢 google安装更新失败,遇到提示需要将googledate加入防火墙白名单。 如何跳过Google 屏蔽 防火墙 为什么我的Google Chrome用的了,但Google网络连不上,Google Play无法下载呢,跪求,亲们拜托了! 北方,冬天喝红茶还是绿茶好 2013手机QQ新增的表情图,叫什么名字啊?像汤圆……… 冬天天冷是不是要喝红茶比较好?不过我特别喜欢和绿茶肿么办。 华为内外屏换多少钱 华为nove现在换屏多少钱 雷锋叔叔抱着迷路的钱孩子这句话怎么画出来。 雷锋叔叔抱着迷路的孩子走在泥泞的路上一脚一个坑怎么画 日美钥匙扣怎么样 这种剃须刀怎么安装? 写给雷锋叔叔明信片怎么制作 金达日美刀身用的什么材料