我正在学习x86汇编语言,我理解段的用途和用法。段包含重要数据,也可用于存储额外数据(即内存分段模型)。这是我的问题。如果段可用于存储额外数据,我如何确保我在其中存储数据不会覆盖任何现有数据?
例如,CS寄存器指向代码段。代码段包含程序的代码。如果我使用带有偏移量的CS寄存器来存储一些数据,我怎么知道放置数据的位置,以免覆盖它存储的代码?
请告诉我。我使用英特尔语法汇编和NASM组装。
由于
答案 0 :(得分:2)
细分从不存储任何数据。段寄存器只是“基”地址指针,用于仅使用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
关于如何确保不使用数据覆盖代码的问题:完全取决于您确保准确知道存储代码和数据的内存位置!
答案 1 :(得分:0)
这是集会,所以你负责一切。保持代码和数据分离就像保持两个数字分开一样简单。只需使用每个内存位置一次。
答案 2 :(得分:0)
除了已经说过的内容之外,我还想补充一点,您通常不希望在代码段中存储任何“数据”。这就是为什么你有一个数据段(DS指向的基础)或甚至是“额外”数据段( - > ES)。显然,由于您的基本假设必须是代码段中的任何内容都将被执行,因此在那里写随机数据值是非常不明智的。
如果必须在代码段中存储数据,请确保它永远不会被执行,如下所示:
..some code here..
jmp AfterDataDeclaration
db 12 ; declare some data here
AfterDataDeclaration:
..some more code here..
[edit:]如果您想访问任何特定数据,您将始终需要一个参考点,您通常最方便通过标签声明该参考点。汇编程序将允许您以符号方式访问它,而无需知道其实际地址。
您可能希望在代码段中编写内容的一种情况是,如果要在那里修补机器代码(即自修改代码)。
答案 3 :(得分:0)
正如他们已经提到的,段寄存器只保存一个16位指针。该指针在内部乘以16,以便CPU可以寻址20位大地址存储空间。
1)如果你有足够的内存,你可以为堆栈选择64Kb的RAM,为数据存储器选择64Kb,为代码存储器选择休息。假设SS(堆栈段寄存器)为0x0400,DS(数据段寄存器)为0x0800,CS(代码段寄存器)为0x1B00。在这种情况下,您的代码不能覆盖任何其他内存段。如果你需要另外64K的数据存储器,你可以使用ES段和ES前缀简单地扩展它。
2)如果没有足够的内存空间(紧凑程序),则必须预测内存边界。
3)如果您的程序使用带内存指针的外部调用,则必须检查边界。为此,在x86助记符中存在BOUND
指令。