2

While running notepad.exe in Ollydbg, I got the following execution trace:

(CPU)
...
[0x00C73689] CALL notepad.0073053
[0x00C7369E] PUSH 58
...

(Memory Map)    
Address    Size     Owner    Section  Contains      Type  Access   Initial  Mapped as
...
000FD000   00002000                                 Priv  RW       Guar     RW
000FF000   00011000                   stack of mai  Priv  RW       Guar     RW
...
00A90000   00001000                                 Priv  RW                RW
00C70000   00001000 notepad           PE header     Imag  R                 RWE
00C71000   0000B000 notepad  .text    code,imports  Imag  R                 RWE
...

Under the virtual address system of windows operation system,

Some address is not in the physical memory or RAM,

  1. Who will translate CALL notepad.0073053 to CALL [Real address 0x??????]?

  2. When that address is file mapped, who will read that value from the disk in assembly language ?

2

You're talking about memory virtualization, which, unless you're developing an operating system, is nothing you have to care about, since it's transparent to user processes.

It's true that the address your program sees, notepad.0073053, is not the same as the one that is physically on the hardware address pins on the processor. But, when the processor executes the call instruction, it doesn't translate the destination address by some magic and puts this translated addres into the program counter - the program counter will. after the call, hold 0x007353.

The virtualization is done in the memory management unit (MMU), which you can think of as a separate piece of hardware between the actual processor and the ram. (Of course, they are on the same chip in modern processors, but there used to be separate MMUs long ago). Think of it this way:

+-----------------+           +----------------------+          +-----------------+
| CPU             |           | MMU lookup table     |          | RAM             |
+-----------------+           +----------------------+          +-----------------+
| call 73053      |  73053    | virtual      | phys. | 63053    |00000            |
| access 73053 on |---------->| 10000-20000  | a0000 |--------->|10000            |
| the address bus |           | 40000-50000  | 30000 |          |20000            |
+-----------------+           | 70000-80000  | 60000 |          |30000            |
                              +----------------------+          |40000            |
                                                                |50000            |
                                                                |60000    X       |
                                                                |70000            |
                                                                |80000            |
                                                                +-----------------+  

The MMU contains a lookup table - which virtual address range maps to which physical addres range. Whenever the processor accesses memory, it tells the mmu which virtual address to access; the MMU uses its lookup table to determine the actual physical address, and that's what it puts on the address bus. But, the processor doesn't care about this translation. What you see in Ollydbg is always the virtual address, never the physical one.

The MMU entries are handled inside the operating system, which may rearrange them as it sees fit. For example, the OS may decide to need the RAM block at 60000 for something else, copy the block at 60000 to, for example, 20000, and update the MMU table. Your program won't notice anything of that - it still accesses the same virtual memory location, which is now at a different place in physical memory.

+-----------------+           +----------------------+          +-----------------+
| CPU             |           | MMU lookup table     |          | RAM             |
+-----------------+           +----------------------+          +-----------------+
| call 73053      |  73053    | virtual      | phys. | 23053    |00000            |
| access 73053 on |---------->| 10000-20000  | a0000 |--------->|10000            |
| the address bus |           | 40000-50000  | 30000 |          |20000    X       |
+-----------------+           | 70000-80000  | 20000 |          |30000            |
                              +----------------------+          |40000            |
                                                                |50000            |
                                                                |60000            |
                                                                |70000            |
                                                                |80000            |
                                                                +-----------------+  

If the operating system decides to page out a memory block to disk, it will clear the corresponding MMU entry. Now, when the processor tries to access that virtual memory, the MMU will generate a page fault, which tells the processor it can't access the memory.

+-----------------+           +----------------------+          +-----------------+
| CPU             |           | MMU lookup table     |          | RAM             |
+-----------------+  73053    +----------------------+          +-----------------+
| call 73053      |---------->| virtual      | phys. |          |00000            |
| access 73053 on |           | 10000-20000  | a0000 |          |10000            |
| the address bus | fault!    | 40000-50000  | 30000 |          |20000            |
+-----------------+<----------| 90000-a0000  | 40000 |          |30000            |
                              +----------------------+          |40000            |
                                                                |50000            |
                                                                |60000            |
                                                                |70000            |
                                                                |80000            |
                                                                +-----------------+

This page fault will make the processor call the page fault handler within the operating system. The OS keeps a list of which pages it has written to disk, finds a memory location that's currently unused, reads the required page from disk to that location, updates the MMU accordingly, then returns to the user program and re-executes the instruction that generated the page fault. The user program won't know anything about that (unless it tries hard to find out, for example by measuring the real time needed and comparing that to the expected time). In Windows, perfmons Ram/Page faults per second counter will tell you how often that happened.

(Actually, there are different kinds of page faults. Space in the MMU tables is quite limited, it normally doesn't map all of a user program's virtual addresses. When a page fault occurs, the OS first checks "Is that block of memory in RAM somewhere, with only the MMU entry missing?". If yes, the OS just generates the MMU entry and allows the program to continue. This is called a minor page fault, which is quite fast to handle; page faults that actually access the disk are called major page faults, and impact performance much more).

1

Sorry, your question is not very clear. Based on what I could understand,

  1. who will translate CALL notepad.0073053 to CALL [Real address 0x??????] ?

You will need to look into the Intel Instruction Set Reference for this. There are many different types of opcode for the CALL instruction. In the code you posted, it uses the following form
CALL rel32/rel16 . The meaning of this is Call near, relative, displacement relative to next instruction. That is, the operand specifies the offset from the immediately next instruction after the EIP (Instruction Pointer). When the processor encounters such code, it merely adds the operand value to the EIP to get the call target. It is important to understand that the disassembled code shown in OllyDbg is only for your understanding. In reality the instruction will only be translated at runtime, when the processor encounters it.

  1. When that address is file mapped, who will read that value from the disk in assembly language?

The PE loader is responsible for loading the executable in memory at the address specified in the PE headers. The ImageBase specifies the address of loading, although in modern Operating Systems, this is not always the case. ASLR (Address Space Layout Randomization) also plays a part in determining the load address.

under the virtual address system of windows operation system, some address is not in the physical memory or RAM,

Virtual Memory is a memory management technique which maps memory addresses used by a program, called virtual addresses, into physical addresses in computer memory. This is implemented in both software and hardware. Paging is a part of virtual memory implementation, which facilitates the use of secondary storage, for storing program data. A situation may occur, in which the processor needs access to data, that is not available in the RAM presently. In such case, the processor will generate page faults. The OS will come to know about this, and will subsequently stall the execution of the program, it will read the pages back from disk into memory, and then execution can continue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.