Explore Windows Memory Mechanism

Source: Internet
Author: User
Memory is the core part of the operating system, so we need to understand the memory allocation mechanism. In dos, the pointer to access the memory is represented by the segment address: Offset. All Programs share the same memory space, from low to high, therefore, any program can modify the data in the memory, including the memory space and the interrupt vector table that does not belong to its own program. In addition, all programs are limited to 1 MB of basic memory and cannot directly access extended memory. For a program in windows, the memory address it accesses is no longer real. It is a virtual, independent flat memory. For example, if a 32-bit program can access the memory address from 0x00000000 to 0 xffffffff (4G), the pointer does not store the segment address. The so-called independence means that when process a loads to the memory 0x400000, the address of process B loads to the memory is 0x400000, and the address space of process B is independent of each other. When the program accesses the memory address, Windows automatically converts it to the actual memory address. In this way, program a cannot directly access the memory space of program B, which improves the system stability.
In fact, in this 4G memory address, we can use less than half of the memory address. Our program cannot allocate memory addresses above 0x80000000. These 2 GB memory addresses are occupied by the system and are read-only. If an application attempts to write a memory address greater than 0x80000000, an "invalid operation" will occur ". Example: char * pstr; If (pstr! = NULL) * PTR = 'a'; a pointer is declared here. It points to 0 xcccccccc when it is not initialized (it is strange to know why all the variables are not initialized, the value is 0 xcccccccc), so it is not empty. Therefore, execute * pstr = "". Because 0xcccccccc is above 0x80000000, an "invalid operation" is generated, which is a common mistake made by some friends.
In Win2000, you can use a 1g address above 0x80000000 (add the parameter/3G in Boot. INI). However, it seems meaningless for common programmers. Win9x memory is slightly different from Win2000 memory allocation. In Win98, the memory available for applications starts from 0x400000, while in Win2000, it starts from 0x100000. However, when an application is loaded, it is always loaded to 0x400000. Try this code: byte buff [0x300]; DWORD dwread; readproccessmemory (getcurrentprocess (), (pvoid) 0x400000, buff, 0x300, & dwread ); please output the buff to the file and you will find that it is exactly the file header of your application.
Windows Memory allocation is based on pages (similar to the disk sector). The size of each page varies with the CPU. The commonly used PC is an X86 architecture, with 4096 bytes per page. You can use the getsysteminfo () function to get the page size. A memory block consists of multiple pages. Each page has an access attribute: page_noaccess cannot access page_readonly read-only page_readwrite read/write page_execute executable ...... We can use DWORD virtualquery (lpcvoid lpaddress, // memory address pmemory_basic_information lpbuffer, // memory address information DWORD dwlength // lpbuffer size, that is, the size of the structure memory_basic_information ); to obtain the status of a memory block. Using virtualqueryex (), you can also access the memory allocation information of other processes. Note that the two functions obtain the information of a memory block rather than a page. In Win9x, when a write operation is performed on a address lower than 0x80000000, even if the memory address is read-only (page_readonly) or the memory is not allocated at all, Win9x generally does not report an error, this improves Win9x compatibility, but also makes Win9x very vulnerable. In Win2000, the page attribute rules are strictly observed. If you attempt to operate on memory addresses with non-write attributes, the operation will be immediately interrupted. This is why many programs can run in Win9x, and the conversion to Win2000 results in illegal operations. Although we cannot directly read the memory space of other processes, windows still leaves us a backdoor: readprocessmemory () and writeprocessmemory (). These two functions can directly read and write the memory of other processes. You may find that if Windows starts two identical applications at the same time (for example, two Visual Studio programs at the same time), the second startup is faster than the first one. This is because, although the memory space of each program is independent, some of them are read-only and can be shared by several processes, including system services that are placed above 0x80000000 memory space. Windows provides this function to effectively save memory space and improve system efficiency. Speaking of this, we have another problem. How can we exchange data normally between two processes, instead of using writeprocessmemory of readprocessmemory to forcibly read and write data? A common method is to map a file to the memory using mapviewoffile (). Other processes can use openviewoffile () to access the file, or use the Windows DDE data transmission protocol. Another access method is to put it in the DLL through: # pragma data_seg ("alluser ").... // data # pragma data_seg () # pragma comment (linker, "/section: alluser, SRW") // set a memory block to public memory for shared read/write, you can access the memory as if you were using a global variable.
If there is such a problem, the following struct occupies a large number of bytes in the memory. Struct {char a [2]; int B;} ABC; maybe you will answer this question. In Windows, char occupies one byte, and INT occupies four bytes, so it is 6 bytes. In fact, if we use sizeof, the size is 8 bytes. In Windows, the default size of memory space allocated to structure variables is a multiple of 8. It is no longer allocated according to the size of its own structure like DOS, because the CPU access alignment data speed is several times faster than the access of non-alignment data. If your data volume is too large and you want to allocate space to the structure based on the actual size, you can set project => setting => C/C ++ => Category => Code Generation => struct member alignment to 1. Allocating non-memory alignment variables also affects execution speed, for example, char * pstr = (char *) malloc (5); DWORD * PDW = (DWORD *) (pstr + 1); The PDW Pointer Points to an odd address, which is time-consuming for PDW operations.
Summary: For a VC programmer, many program errors occur in memory allocation, such as using a null pointer without checking, if you can manage and allocate the memory space of your program, your program will have fewer unnecessary errors.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.