Hi,
can anyone tell me how to access a specific memory location in C++ (I use Dev-C++ 4.9.9.2) without the OS giving me an error and stopping the execution of my prog? I've tried the following code on both WinXP and Win98, but they both gave me an error :

#include<iostream>
#include<conio.h>

int main()
 {
    using namespace std;

    int *p;
    p = (int *) 0x378;     //0x378 is the memory location I'm trying to access

    //If I enter 'cout<<p<<endl;', prog executes and outputs '0x378'
    //But if I dereference the pointer, 'cout<<*p<<endl;', the OS gives me an error
 }

I've also tried a couple of different addresses, but the results are the same...
Thanks

Recommended Answers

All 17 Replies

Hi there!

Am I correct in assuming you want to access the parallel port?
You may be better using CreateFile("LPT1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

Then using ReadFile and WriteFile to read and write data over the port using the handle that "CreateFile" generates.

The reason you cannot access it directly is because it exists in an area of memory that User Mode applications are not allowed to access. If you wanted to get access to this specific address, then you *must* write a device driver to do it.

Never ever try to access a memory location like that. You have no idea what's stored in that memory location. Anyway, how did you come up with that particular number of 0x378? The purpose of pointer is to reference a memory location where it holds a value of interest to you (either you want to read or overwrite that value). Here's an example of using pointer.

int a = 0;
int *p;

p = &a;   // p points to a

In the example above, I am not aware of the address of the memory (I do not need to care about the address). All I know is that my integer pointer 'p' is now pointing to the same element as 'a'. Hope this helps.

tnks for your replies!

@katsuekiame, yes you're right, I was trying to access the printer port's memory! I'm trying to learn how to control the printer port so that I can control a primitive flatbed plotter I've built from old printer parts (just for fun)...

@chiwawa10, I was trying to access that specific memory location because I had to access the printer's memory register...

btw, does anyone know what are memory segments?
The thing is, I can access memory addresses very easily with QBasic's peek and poke functions, but before using any of those functions, you have to use the DEF SEG function (QBasic's on-line help defines this function as 'a memory statement that sets the current memory segment address for a subsequent PEEK or POKE function')

so the following code in QB:

DEF SEG = 0
PEEK (888)     '888 is the decimal equivalent of 0x378

is different from this:

DEF SEG = 1
PEEK (888)

I need to know which memory segment I need to use to access the right address...
Tnks again!

Ok, I think you'll need a file called inpout32.dll

Check this link for all the information you should need

Thanks again...

tnks for your replies!

@katsuekiame, yes you're right, I was trying to access the printer port's memory! I'm trying to learn how to control the printer port so that I can control a primitive flatbed plotter I've built from old printer parts (just for fun)...

@chiwawa10, I was trying to access that specific memory location because I had to access the printer's memory register...

btw, does anyone know what are memory segments?
The thing is, I can access memory addresses very easily with QBasic's peek and poke functions, but before using any of those functions, you have to use the DEF SEG function (QBasic's on-line help defines this function as 'a memory statement that sets the current memory segment address for a subsequent PEEK or POKE function')

so the following code in QB:

DEF SEG = 0
PEEK (888)     '888 is the decimal equivalent of 0x378

is different from this:

DEF SEG = 1
PEEK (888)

I need to know which memory segment I need to use to access the right address...
Tnks again!

DEF SEG gets a segment of memory. In QBasic this is the high-order 16bits from the memory segment you wish to work in.

The peek and poke then works with the low-order 16 bits.

So your code effectively sets the high order segment to work with to 0, and then requests what's being held at memory address 0x378 (888 to hex is 0x378)
The following will read the memory from address 1234ABCD:

def seg = &H1234
peek &HABCD

So you first define you wish to work with memory segment "12340000" to "1234FFFF"
Any subsequent peeks or pokes will goto "1234xxxx" where xxxx is the address you specify.

The reason this will work in QBasic is because it QB works in DOS. In DOS there was/is no memory protection. You can read and write from and to any memory location.

Oh now I get it!

Tnks for the explanation, it really helped...

Regarding the printer, I opened the Device Manager (using WinXP) and opened the Properties window for my printer (LPT1), and in the Resources tab I found the following:

Resource type Setting

I/O Range 0378-037F
I/O Range 0778-077F
DMA 03

I know that location 0378 is the one dedicated for the printer, but what are all the other locations used for? Also, what is DMA?

tnks

For all you know, the rest of them *could* be nothing, however I believe they're reserved for additional LPT ports, or for the port settings, but I'm not 100% sure

DMA stands for Direct Memory Access. This goes way back to DOS. Everything used to have a different Direct Memory Access number. You could then access the device using the DMA number and it bypasses the processor. It's put into use automatically now using Programmed I/O. (If you didn't use DMA, the processor would have to completely dedicate itself to the task of reading and writing to the port. Slowing down your machine to a near crawl in computing terms)

In the modern Windows OS, everything is mapped into the lower address space and exists in ring0 also known as kernel mode. This is kept separate to User Mode, or ring3, where your apps run. Drivers can re-map kernel mode to user mode and vice versa effectively becoming a proxy.

Tnks for the reply, I managed to understand most of it - with the help of my dad

If you don't mind, I have another question...
I was desperate to see some results so I made a program in QB which altered the value at memory address HEX378 (I set DEF SEG to 0 and POKEd memory 888 with a value of 255) on my Win98 pc. I tested all the pin's outcomes (1 to 17, as 18-25 are ground) before alteration, and after. The outcomes were the same.

So, my question is : Is it really that simple? To alter the parallel port's outcome, do you simply have to change the contents at memory address HEX378?

tnks

Yes. You should send data in accordance to which pin you want to set "on".

Your data pins are pin2 to pin9 (making 8 data pins) There are 5 status pins (10, 11, 12, 13 and 15) and 4 control pins (1, 14, 16, 17) the rest are ground.

Your 8 pins can be represented in binary. 0000 0000 starting from the RIGHT is pin2 (or data pin1) so to send data down datapin1 you would send 0x01 to address 0x378.
to turn on datapin8 you would send 0x80.

Sending 0xF2 would turn on 1111 0010 (so pins 8, 7, 6, 5, 4, 2)
Sending 0x03 would turn on 0000 0011 (so pins 1 and 2)

Sending 0x00 would turn off all pins.


Hope this helps.

Ahh ok...
Thanks a million, I think that's all I need to know for now...

Cheers,
Dean

Ah I forgot to mention.

The parallel port is exactly that, parallel. Every command sets the 8 data bits in parallel.

So if you take my two examples above and send 0xF2 followed by 0x03
When you send 0x03 all the pins you previously turned on would be turned off except for datapins 1 and 2.

0xF2 ---> 1111 0010 <--- Pin outcome
then;
0x03 ----> 0000 0011 <--- Pin outcome

Final Pin Outcome is 0000 0011 and NOT 1111 0011.

I say this because I've seen people assume the latter before.

So, lets say I want to achieve a pin outcome of 11110011, would I have to 'bitwise-OR' 0xF2 and 0x03 together, or am I using the wrong logic?

You could do, but it's easier just to say 0xF3. But yes, if the situation were required, you could bitwise-OR and send the cumulative result.

You can actually think of the two "numbers" after the 0x as seperate segments of 4. The first number representing pins 8-5 and the second number represents 4-1.

0x F    2
   1111 0010
0x 0    3
   0000 0011

So control pins 5 to 8 set the first number after the 'x' and to set pins 1 to 4 set the second number.

Oh OK tnks...
Now I know enough to began coding...

Good luck and let me know how it turns out :)

I will dw...

To tell you the truth, despite all the help you, my dad and other programmers have given me, I don't really expect all this to work, I mean there are too much things which could go wrong... but I will try my best...

Regards,
Dean

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.