1

我正在学习 x86 汇编语言,我了解段的用途和用法。分段保存重要数据,也可用于存储额外数据(即内存分段模型)。这是我的问题。如果段可用于存储额外数据,我如何确保我在其中存储的数据不会覆盖任何现有数据?

例如,CS 寄存器指向代码段。代码段包含程序的代码。如果我使用带有偏移量的 CS 寄存器来存储一些数据,我怎么知道将数据放在哪里以免覆盖它正在存储的代码?

请告诉我。我使用 Intel 语法汇编和 NASM 汇编。

谢谢

4

4 回答 4

3

段从不存储任何数据。段寄存器只是“基”地址指针,用于仅使用 16 位寄存器创建 20 位指针。例如:

MOV DS, 0001
MOV DI, 0013
MOV AL, DS:[DI]  ' this reads from address x00023 in memory

MOV DS, 0002
MOV DI, 0003
MOV AL, DS:[DI]  ' this too reads from address x00023 in memory

MOV DS, 0000
MOV DI, 0023
MOV AL, DS:[DI]  ' this too reads from address x00023 in memory

至于您的问题,如何确保您不会用数据覆盖代码:这完全取决于您确保您确切知道在内存中存储代码和数据的位置!

于 2009-10-23T08:52:43.020 回答
0

正如他们已经提到的,段寄存器只保存一个 16 位指针。该指针在内部乘以 16,以便 CPU 可以寻址 20 位大地址存储空间。

1)如果你有足够的内存,你可以选择 64Kb 的 RAM 用于堆栈,64Kb 用于数据存储器,其余用于代码存储器。假设 SS(堆栈段寄存器)为 0x0400,DS(数据段寄存器)为 0x0800,CS(代码段寄存器)为 0x1B00。在这种情况下,您的代码不能覆盖任何其他内存段。如果您需要另外 64K 的数据内存,则可以使用 ES 段和 ES 前缀简单地扩展它。

2)如果您没有足够的内存空间(紧凑程序),则必须预测内存边界。

3)如果您的程序使用带有内存指针的外部调用,则必须检查边界。为此,x86 助记符存在BOUND指令。

于 2009-10-23T16:39:59.193 回答
0

除了已经说过的内容之外,我想补充一点,您通常不希望在代码段中存储任何“数据”。这就是为什么你有一个数据段(由 DS 指向的基础)甚至是一个“额外的”数据段(-> ES)。显然,由于您的基本假设必须是代码段中的任何内容都将被执行,因此在此处写入随机数据值是非常不明智的。

如果您必须在代码段中存储数据,请确保它永远不会被执行,如下所示:


..some code here..
jmp AfterDataDeclaration
  db 12  ; declare some data here
AfterDataDeclaration:
..some more code here..

[编辑:]如果你想访问任何特定的数据,你总是需要一个参考点,你通常最方便地用标签声明它。汇编器将让您以符号方式访问它,而无需知道它的实际地址。

您可能想在代码段中写一些东西的一种情况是,如果您想在那里修补机器代码(即,自修改代码)。

于 2009-10-23T12:07:30.290 回答
0

这是组装,所以你对一切负责。将代码和数据分开就像分开两个数字一样简单。最多只使用每个内存位置一次。

于 2009-10-23T10:34:37.730 回答