通过汇编将数据存储在段中
我正在学习x86汇编语言,我了解段的目的和用法。段保存重要数据,也可用于存储额外数据(即内存分段模型)。不过,这是我的问题。如果段可用于存储额外的数据,我如何确保在其中存储的数据不会覆盖任何现有数据?
例如,CS寄存器指向代码段。代码段包含程序的代码。如果我使用带有偏移量的 CS 寄存器来存储一些数据,我如何知道将数据放在哪里以免覆盖它存储的代码?
请告诉我。我使用 Intel 语法汇编并使用 NASM 进行汇编。
谢谢
I am learning x86 assembly language, and I understand the purpose and usage of segments. Segments hold vital data, and can also be used to store extra data (ie. Memory Segmentation Model). Here is my question though. If segments can be used to store extra data, how can I make sure that my storing data in them won't overwrite any existing data?
For example, the CS register points to the Code Segment. The Code Segment contains the program's code. If I used the CS register with an offset to store some data, how would I know where to put my data so as not to overwrite the code that it is storing?
Please let me know. I using Intel syntax assembly and assembling with NASM.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
段从不存储任何数据。段寄存器只是“基”地址指针,用于仅使用 16 位寄存器创建 20 位指针。例如:
至于您的问题如何确保不会用数据覆盖代码:这完全取决于您确保您确切知道在内存中存储代码和数据的位置!
Segments never store any data. The segment registers are just "base" address pointers which are used to create 20-bit pointers using only 16-bit registers. For example:
As for your question how to make sure that you don't overwrite code with data: it's entirely up to you make sure that you know exactly where in memory you store your code and data!
这是组装,所以你要对一切负责。将代码和数据分开就像将两个数字分开一样简单。每个内存位置最多只使用一次。
It's assembly, so you are responsible for everything. To keep your code and data separate is just as easy as keeping two numbers separate. Just use each memory location at most once.
除了已经说过的内容之外,我想补充一点,您通常不想在代码段中存储任何“数据”。这就是为什么你有一个数据段(DS 指向的基址)甚至一个“额外”数据段(-> ES)。显然,由于您的基本假设必须是代码段中的任何内容都将被执行,因此在那里写入随机数据值是非常不明智的。
如果必须在代码段中存储数据,请确保它永远不会被执行,如下所示:
[编辑:]如果您想访问任何特定数据,您始终需要一个参考点,通常可以通过标签方便地声明该参考点。汇编器将允许您以符号方式访问它,而无需知道其实际地址。
您可能想要向代码段写入某些内容的一种情况是,如果您想要在那里修补机器代码(即自修改代码)。
In addition to what's been said already, I'd like to add that you wouldn't normally want to store any "data" in the code segment. That's why you have a Data Segment (base pointed to by DS) or even an "extra" data segment (-> ES). Obvisouly, since your basic assumption must be that whatever is in the code segment, will be executed, it would be very unwise to write random data values there.
If you must store data in the code segment, make sure it will never be executed, like below:
[edit:] If you want to access any specific data, you will always need a reference point, which you will usually most conveniently declare by a label. The assembler will let you access this symbolically, without you having to know its actual address.
The one case where you might want to write something to the code segment is if you want to patch machine code there (i.e., self-modifying code).
正如他们已经提到的,段寄存器仅保存一个 16 位指针。该指针在内部乘以16,以便CPU可以寻址20位大地址存储空间。
1) 如果您有足够的内存,则可以选择 64Kb RAM 用于堆栈,64Kb 用于数据内存,其余用于代码内存。假设SS(堆栈段寄存器)为0x0400,DS(数据段寄存器)为0x0800,CS(代码段寄存器)为0x1B00。在这种情况下,您的代码无法覆盖任何其他内存段。如果您需要另外 64K 的数据存储器,则可以使用 ES 段和 ES 前缀简单地扩展它。
2)如果您没有足够的内存空间(紧凑程序),则必须预测内存边界。
3)如果您的程序使用带有内存指针的外部调用,则必须检查边界。为此,x86 助记符中存在
BOUND
指令。As they already mentioned, segment register hold only a 16 bit pointer. This pointer is internally multiplied by 16 so that CPU can address 20-bit big address memory space.
1) If you have enough memory than you can choose 64Kb of RAM for stack, 64Kb for data memory and rest for code memory. Let say that SS (stack segment register) is 0x0400 and DS (data segment register) is 0x0800 and CS (code segment register) is 0x1B00. In this case your code can't override any other memory segment. If you need another 64K of data memory than you can simple extend it with use of ES segment and ES prefix.
2) If you don't have enough memory space (compact program) than you must predict the memory boundaries.
3) If your program use external calls with memory pointers than you must check boundaries. For this purpose in x86 mnemonic exist
BOUND
instruction.