| | | | the machine language instruction to place the value 5 in that location might look something like the following (in assembly language): | | | | | | mov dword ptr [01000100], 5 | | | | | | Note the presence of the base address. In short, the base address of the executable is hardcoded into the executable. | | | | | | A similar problem arises when a call is to a function that is contained in a different module (such as another DLL). If the base address of the other DLL is, say, &12000000, the jump instruction would be relative to that base address. | | | | | | Now, the problem is that there is no guarantee that a module will be loaded at its default base address. In fact, only one module can be loaded at any given address, and, as you can see from our process viewing utility, a process space may have a great many modules. It is not surprising that two modules might have the same default base address. | | | | | | Fortunately, Microsoft has been careful about assigning default base addresses to its modules in such a way as to minimize conflicts. You can see this by browsing the rpiEnumProcs utility. However, all modules that we create in VB (or VC++) will have the same default base address unless we specify otherwise. | | | | | | In order that a module be relocatable, executable files contain relocation information for the relocatable code in the file, that is, the code that may need adjustment if the file is not loaded at its default base address. This relocation information is also called fixup information or fixups. | | | | | | Now, if a module needs to be relocated for a particular process, its relocatable code needs to be changed for that process, but not for any other process that is using this module. Suppose, for instance, that Process1 has Module1 loaded into its address space at Module1's default address. Process2 wants to load Module1, but it already has a module loaded at Module1's default base address. Thus, Module1 will need to be relocated in Process2's address space, which will necessitate some changes to the relocatable code in Module1. Since Process1 cannot tolerate any changes to the code for Module1, Windows must make a new physical copy of Module1 so that it can perform the necessary fixups and map the module into the virtual address space of Process2. This is done using the copy-on-write mechanism that we discussed earlier. | | | | | | The point, of course, is not only that this copy-on-write process requires additional processor time, but also that the new physical copy of the module uses additional precious physical memory. Thus, it behooves us to attempt to minimize base address conflicts when creating modules. | | |