将值分配给特定地址
这是一道面试题,我是在一本面试书上看到的,后来在一次面试中也遇到了这个问题。
问题是
如何将值(例如
0
)分配给地址(例如0x12345678
)。
我对这个问题的最佳尝试(面试后很长一段时间后)是
地址是一个可以存储在指针中的数字,我们可以通过指针给该地址赋值,该值就是地址,例如:
int* p = 0x12345678;
*p = 0;
但是,在具有内存管理的系统上这是不可能的,因为程序没有特定地址的特权。
根据我自己的经验,这种操作唯一有效的一次是在没有任何操作系统的8086芯片上进行的实验,而我当时使用的语言是汇编。
请帮助我纠正、改进和完成我的答案。谢谢。
It is an interview question, which I came across at a book for interviews, and later in an interview.
The question is
How to assign value (say
0
) to an address (say0x12345678
).
My best try for this question (after a long time after the interview) is
An address is a number which can be stored in a pointer, and we can assign a value to the address by a pointer, the value of which is the address, like:
int* p = 0x12345678;
*p = 0;
However, it is not possible on a system with memory management, because the program does not have privilege to the specific address.
According to my own experience, the only time this kind of operation was valid was the experiment on an 8086 chip without any operation system, and the language I used that time was assembly.
Please help me correct, improve and complete my answer. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的代码是正确的,但如果操作系统将 0x12345678 定义为只读,则可能会破坏运行时。
虽然“常规”操作系统可以做到这一点,但“较轻”的操作系统却不能。
您想编写一个内核空间黑客程序来做到这一点。
如果你想看一下,我为Linux解决了这个问题:
1)构建这个模块(example.ko):
2)将其添加到内核模块:
3)在列表中找到模块的“主要”:
4)使节点与设备:
“c”代表字符设备,“minor”可以是 0-255 中的任何一个
5) 在代码中将设备用作文件:
Your code is correct but might crush on runtime if the OS defines 0x12345678 as read-only.
While a "regular" OS does that, "lighter" ones do not.
You want to write a kernel-space hacking program to do it.
I solved it for linux if you like to take a look:
1) build this module (example.ko):
2) add it to kernels modules:
3) find the module's 'major' in the list:
4) make node associated with the device:
'c' is for character device and 'minor' can be any of 0-255
5) use the device in your code as a file:
(几乎)不可能知道哪些内存位置可写入。
您可以使用 malloc() 函数要求操作系统为您提供一个可用地址,然后使用 free() 释放该位置。
另一种方法是使用堆栈内存。只需定义一个变量 int *p = 0; &p 将为您提供该位置的地址。
如果您尝试将值分配给不可用的位置,则可能会出现分段错误。
希望这有帮助!
It is (nearly) impossible to know which memory locations are available to write to.
You can ask the OS to give you an available address by using malloc() function and later freeing that location up by using free().
Another way is to use the stack memory. Just define a variable int *p = 0; &p will give you the address of this location.
If you try to assign values to locations which are unavailable, you might end up with segmentation fault errors.
Hope this helps!
即使在具有内存管理的系统中,这种事情也绝对是可能的,如果指针位于当前进程的可访问空间之外,它就会出错,但这就是应该发生的情况。如果没有,该值将被设置并继续。除此之外,你的例子对我来说似乎很好。
That sort of thing most definitely IS possible even in systems with memory management, if the pointer is outside accessible space for the current process, it'll fault, but that's what's supposed to happen. If not, the value is set and on you go. Other than that, you're example seems fine to me.
答案是函数-> mmap() 。如果您的设备具有相同的实际地址,则可以将您的虚拟地址映射到实际地址,然后您可以使用虚拟地址进行操作。
在linux中,首先需要通过函数->打开设备内存空间作为文件open(),并设置文件的属性。将缓存页面映射到该虚拟文件并接收指针之后 ->映射()。在使用映射内存空间之前需要通过函数->同步DATA msync()。使用内存后,在关闭程序之前需要取消映射内存缓存 -> munmap() 并关闭虚拟文件 close()。关于详细功能描述请在google中搜索解释:)
The answer is function -> mmap() . If you has same really address of device, it's possible mapping your virtual address to really address and after it you can operate with virtual address.
In linux, firstly need open the device memory space as file by function -> open(), and set perditions of the file. After it mapping caching page to this virtual file and receive pointer -> mmap(). Before using mapping memory space needed synchronize the DATA by function -> msync(). After using the memory, before close program you need unmapping memory cache -> munmap() and close virtual file close(). About detail functions description search explain in google :)
也许答案是没有答案,因为在有内存管理的系统中这是不可能的。
在没有内存管理的系统中,我会直接尝试使用汇编代码。
希望有帮助
Maybe the answer is that there is no answer because it is impossible in a system with memory management.
In a system without memory management I would try with assembly code directly.
Hope it helps