数据段, 代码段, 栈段的一点理解

我们知道, 一个程序要运行, 首先要将程序加载进入内存中, 然后运行其中的代码, 同时, 我们的程序也会在运行过程中, 保存一部分数据到内存中.
我们知道, 可以运行的代码, 例如求解一个方程组, 都是放在代码段中的
数据段中则会存放一些初始化数据, 例如我们的已经初始化的全局变量
而栈段则会存放运行中的堆栈信息, 临时变量等.
当然还会有堆区等其他区段, 这里暂且忽略.
对于计算机来讲, 所有的代码和数据都可以2进制形式存放在内存中, 那么对于某一个特定的内存地址, 我们如何辨别这个数据是代码还是普通数据?

总所周知, cpu 内部有若干寄存器, 有些寄存器是通用寄存器, 可以存放普通的数据, 例如用来存放加法指令的结果.
而还有些则有自己特定的功能.
对于代码段来说, cpu 需要知道当前的代码在内存中的哪个位置, 这一点, 就是靠的CS, IP 寄存器(8086 CPU, 下同).
例如, 当CS 为 0x1000, IP 为 0x0001, 那么下一句代码的位置就在 CS*0x10+IP = 0x100001 这个地址. CS 就是代码段地址, 而IP 则是代码段偏移量, 可以看到, 当前有一个代码段位于 0x10000 处.
当cpu 需要从内存中读取某个全局变量时, 则会用到另外一个寄存器, DS, 例如我们有一个全局变量位置在 0x20005 处. 我们如果要读取可以使用类似下面的指令

mov ds, 0x2000; 给ds 寄存器赋值, 相当于 ds=0x2000,实际上没有这个指令, 并不能直接给ds 赋值, 需要使用其他寄存器中转, 类似于 ax=0x2000; ds=ax 这样. 这里为了方便理解, 就这样写了.
mov ax, [5]; 读取制定内存位置的数据到寄存器中. [5]表示偏移量, 偏移量是相对于ds 来说, 这里就相当于 ax=*((int*)(ds+5))

也就是说, DS 寄存器标识了一个段, 我们这里存在一个段在 0x2000 处.
同理, 栈也有寄存器, SP 和 SS, SS 表示栈顶, SP 标识偏移量, SS 就标识了一个栈段.

这里就存在一个问题, 起始我们是可以任意修改这些寄存器的, 也就是说, 何处是代码段, 何处是数据段是我们自己规定的, CPU 并不知道, 它只知道CS:IP 这个地方的数据需要读取出来运行, 而 SS:SP 这个位置, 可以读取一个栈的数据.
所有的一切, 都只是我们的一厢情愿. 你如果错误的将CS:IP 指向了一个数据段的地址, 那么CPU 运行时可能就直接异常退出了, 同理, 当尝试从代码段读取数据时, 也只会读到一段莫名其妙的数据.CPU 并不会帮你处理这些异常的行为, 一切都在你自己手里.
还有一个问题, 就是这些寄存器都只有一个起始位置, 并没有一个能表示长度的寄存器, 特别是对于栈段.例如, 我们规定0x30000-0x3000F 保存的是栈中的数据, 0x30010-0x3001F 保存的是代码, 那么如果我们在栈区多次pop, 就有可能跑道代码区里面去了, 就有可能会错误修改代码区数据, 导致程序无法正常运行.

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 8086汇编 本笔记是笔者观看小甲鱼老师(鱼C论坛)《零基础入门学习汇编语言》系列视频的笔记,在此感谢他和像他一样...
    Gibbs基阅读 37,867评论 8 114
  • 王爽汇编全书知识点大纲 第一章 基础知识 机器语言 汇编语言的产生 汇编语言的组成 存储器 cpu对存储器的读写 ...
    2c3ba901516f阅读 7,334评论 0 1
  • 组件 计算机是一种数据处理设备,它由CPU和内存以及外部设备组成。CPU负责数据处理,内存负责存储,外部设备负责数...
    哆啦灬少A梦阅读 5,598评论 1 2
  • 做完作业,时间已是有些晚了,催着儿子赶紧洗刷,伺候完小家伙后我还得去接姐姐。人家可不领会你的心情,一边慢吞...
  • 落叶知秋.树叶飘零,秋天来临了. 有人说:秋天是思念的颜色.也许是吧.不然,为什么当我看到满地的枯叶,我会置于...
    豆芽粒阅读 1,184评论 0 0

友情链接更多精彩内容