Author Topic: Accessing Memory Directly in Protected Mode  (Read 4695 times)

Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Accessing Memory Directly in Protected Mode
« on: October 22, 2018, 03:07:02 AM »
Hi again everyone.

I am trying to teach myself a little about Windows 7 Protected Mode.

At the end of this post I have 2 questions.

Using NASM I was able to successfully compile this file (let's call it tiny1.asm) -

tiny1.asm
Code: [Select]

cpu 586
bits 32
flat

section .text
use32

global _mainCRTStartup

_mainCRTStartup:

push dword eax

mov dword eax,[0x00010000] ; works
mov dword eax,[0x0001fffc] ; works

pop dword eax

ret


I used NASM version 0.98.39 and I used this command line to create the tiny1.obj file -
Code: [Select]
NASM.EXE -f win32 tiny1.asm

I then used GNU ld (GNU Binutils) version 2.30 and I used this command line to create the tiny1.exe file -
Code: [Select]
ld.exe --disable-auto-import --strip-all tiny1.obj -subsystem windows -o C:\tiny1.exe

And this created tiny1.exe that executes without error when run as administrator.

However, if I change the memory address in my tiny1.asm file slightly I get what I assume is a General Protection Fault error (even though I am using the same NASM and ld command lines) -

Code: [Select]

cpu 586
bits 32
flat

section .text
use32

global _mainCRTStartup

_mainCRTStartup:

push dword eax

mov dword eax,[0x00020000] ; General Protection Fault error?

pop dword eax

ret


I think that Windows 7 allocates memory and hardware resources when I run my tiny1.exe file.

My 2 questions are -
1 - Why does memory location 0x0001fffc work but 0x00020000 not work?
2 - When Windows 7 allocates 'my sandbox', is there a website or link that has the directly accessable memory locations that are available to me?
(For instance - in this example - In Windows 7 - memory locations 0x00010000 to 0x0001fffc are available to me to access directly)

I understand that directly accessing memory is not recommended, but like I said at the beginning of this post, I am trying to teach myself Windows 7 Protected Mode programming and I am trying to experiment around with it.

I have included my tiny1.exe file as an attachment if anyone else wants to examine or try it on their computer.

Thank you in advance for any information on NASM Protected Mode programming

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Accessing Memory Directly in Protected Mode
« Reply #1 on: October 22, 2018, 05:20:56 PM »
General Protection Fault is too broad of a topic. It has nothing to do with "nasm protected mode". #GP is basically triggered by the CPU for various memory-related reasons, most likely by an unmapped virtual memory reference being requested by an application. But the OS can also disguise somewhere in there via one of its exception handlers. It could be your absolute addressing mode pointing to a protected/privileged memory area (writeable, executable, readable etc), or simply referencing a memory out of the allocated range / pages. AFAIK, the OS has its own arithmetic in calculating your addresses / offsets, mostly hidden from programmers. And there are lots of other evil reasons as well.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2597
  • Country: us
Re: Accessing Memory Directly in Protected Mode
« Reply #2 on: October 22, 2018, 08:25:22 PM »
Thanks dreamCoder! The tip that frankly probably needs is "virtual memory". Wikipedia has some info. or OS development groups, or Intel/AMD manuals.

When the CPU starts, it is in "real mode". I don't know why they call it "real", except perhaps that our only access to memory is to real physical memory. An address is formed by multiplying the value in a segment register by 16 and adding it to an offset. We get into "protected mode" (it is protected from us!) by setting bit 0 of cr0 - one of our "control registers". This changes the meaning of the segment registers to a "selector" - an index into a "descriptor table". We have to have a descriptor table loaded before doing this. A descriptor includes some bits that control  access rights... but this is probably not where access is controlled. We can set another bit - I think it's bit 31- which enables virtual memory. Another control register (as I recall) points to a "page directory" which points to "page tables" which control the mapping of virtual memory to physical memory. Virtual memory is what we access in protected mode. You may have noticed that you can run two instances of "tiny.exe" and they both access 0x10000 without bumping into each other. That's what's happening - two instances of virtual memory are mapped into different physical RAM. If you attempt to access virtual memory which is not mapped at all, or if you attempt to write to memory mapped as read-only. you'll get a GPF - I know it as "seg fault, but it's the same thing.

You're using an insanely obsolete version of Nasm. That probably isn't hurting you. There were many bugs fixed beside the added features, but you probably won't encounter them. You include some code that doesn't do anything. That won't hurt you, either. You fail to exit cleanly (ret, at least, preferably ExitProcess) which allows the CPU to execute whatever code happens to be there. This random code probably won't format your hard drive, but you probably want to avoid it!

Best,
Frank




Offline frankly

  • Jr. Member
  • *
  • Posts: 21
Re: Accessing Memory Directly in Protected Mode
« Reply #3 on: October 23, 2018, 12:35:12 AM »
Thank you dreamCoder and Frank for replying so quickly!

And thank you for the Virtual Address information.

I am guessing that one of the instructions from my original post...
mov dword eax,[0x00010000]
...is not actually looking at the physical memory address location of 0x00010000 but instead is looking at a virtual memory address location which could be almost anywhere in physical memory.

So based on what you said...

#GP is basically triggered by the CPU for various memory-related reasons, most likely by an unmapped virtual memory reference being requested by an application. But the OS can also disguise somewhere in there via one of its exception handlers. It could be your absolute addressing mode pointing to a protected/privileged memory area (writeable, executable, readable etc), or simply referencing a memory out of the allocated range / pages.

This changes the meaning of the segment registers to a "selector" - an index into a "descriptor table". We have to have a descriptor table loaded before doing this. A descriptor includes some bits that control  access rights... but this is probably not where access is controlled. We can set another bit - I think it's bit 31- which enables virtual memory. Another control register (as I recall) points to a "page directory" which points to "page tables" which control the mapping of virtual memory to physical memory. Virtual memory is what we access in protected mode.

... it looks like I have a lot more to learn about Virtual Memory in Protected Mode.

Thank you both again for your quick and thorough replies!

If/When I have the time in the future, I will find more information about selectors, the descriptor table, the page directory, page tables, etc. and when I understand Virtual Memory fully, I will reply to this thread with either a understandable breakdown of how protected memory works, or links to understandable breakdowns that I think will be helpful for other beginner programmers that want to learn about Virtual Memory in Protected Mode.

-Frankly