Help with pointers and absolute memory addresses

I

Ian Collins

Yep said:
Hi Guys,

I have some confusion with pointers and implicitly specifying a size of
memory to write.

I will try to explain what I am trying to do a bit better.

char *myaddress=(char *) 0xB8000;

now, I can say something like:

*myaddress=3;

And the 8 bit value of '3' will be written at absolute address 0xB8000

What if I want to explicitly write a 16 or 32 bit value to that address?

Just follow the same pattern,

T *myaddress = (T*)0xB8000;

*myaddress = someT;
 
W

Walter Roberson

Yep said:
I have some confusion with pointers and implicitly specifying a size of
memory to write.
char *myaddress=(char *) 0xB8000;
(unsigned short *) *myaddress=somevalue;
Compiles but generates compiler warnings about lvalue of cast not being
standard C.

Unfortunately for your purposes, standard C leaves it up to the
implementation to define what (if any) meaning there is to
converting an integer into a pointer, and what (if any) meaning
there is to accessing the resulting location.


That said: you would be better off trying:

*(unsigned short *)myaddress=somevalue;
 
Y

Yep

Hi Guys,

I have some confusion with pointers and implicitly specifying a size of
memory to write.

I will try to explain what I am trying to do a bit better.

char *myaddress=(char *) 0xB8000;

now, I can say something like:

*myaddress=3;

And the 8 bit value of '3' will be written at absolute address 0xB8000

What if I want to explicitly write a 16 or 32 bit value to that address?
Obviously I need to use casts to do this but my memory is terrible and
the compiler is unhappy with what I try.

Say for example:

unsigned short somevalue=0xffff; //watcom C unsigned short = 16 bit Uint

Now I want the content of 'somevalue' to be written at absolute address
'myaddress'

Whats the correct way to do this?

(unsigned short *) *myaddress=somevalue;

Compiles but generates compiler warnings about lvalue of cast not being
standard C.I have actually looked at the assembly code output this code
produces and it it not writing the correct size to that address.

Any suggestions/relevant reading tips would be appreciated, if the
advice is going to be about documentation on pointers, i need reading
that deals with this very subject.

Thanks in advance.
Alex.
 
I

Ian Collins

Yep said:
That works! Why is the extra * needed in front of the cast?

Maybe writing the expression as

*((unsigned short *)myaddress) = somevalue;

makes it clearer?
 
Y

Yep

Richard said:
Yep said:


Is this an attempt to scribble on video RAM on an x86? If so, be warned
that you'll need to be in real mode for it to work (more about that in
comp.os.msdos.programmer). Also, I would recommend unsigned char * for
this!

I used this as an example :) I am writing under 32 Bit Pmode in DOS, so
B8000 is correct (sorry for the off topicness), but the code will be
used to control peripherals with their MMAP'd space on the PCI bus.
Close. 3 rather than '3'. Assuming for the moment that we're using 8-bit
char, 16-bit int, and ASCII: 3 is the bit-pattern 0000000000000011 (so the
8-bit equivalent would be 00000011), whereas '3' is the bit pattern
00110011. As you can see, these are not quite the same!

My bad. I shouldnt have put '' but yes, the value of 3 in binary, not
ascii. But to be technically correct writing a word value of 0x7f50 will
put a capital 'P' in white text on grey background on the screen, a
dword value 0x7f507f50 will put 2 of them as the ordering is
attrib,character.
Final warning: this is *so* not a good idea. BAD BAD BAD IDEA, okay? Bad.
If you insist on doing this, you will NOT get a biscuit.

Nevertheless, if you must do it, that's one way to do it.

There is a reason for it. I need to be able to write explicit 8, 16, 32
bit values to any address within the 32 bit address space. This is
allowed on the platform I am writing (32 Bit Pmode under DOS).
 
Y

Yep

Ian said:
Maybe writing the expression as

*((unsigned short *)myaddress) = somevalue;

makes it clearer?

It does.

So its a pointer to the unsigned short, pointed to by myaddress.

I did a test case:

*((unsigned long *)myaddress) = somevalue; //32 bit
*((unsigned short *)myaddress) = somevalue; //16 bit
*((unsigned char *)myaddress) = somevalue; //8bit

And observed the assembly code generated by the compiler, the behavior
is correct.

Thank you!!!!!
 
S

santosh

Yep said:
It does.

So its a pointer to the unsigned short, pointed to by myaddress.

I'm not clear about what you are saying above but that line actually
takes the value of myaddress (which is the address it holds) which of
type char * and explicitly converts it to a value of type unsigned
short *, then deferencing this value to write somevalue.
I did a test case:

*((unsigned long *)myaddress) = somevalue; //32 bit
*((unsigned short *)myaddress) = somevalue; //16 bit
*((unsigned char *)myaddress) = somevalue; //8bit

These are the least sizes that the C standard requires but they *could*
be bigger on some platforms. At least on the x86_64 under some OSes
long is actually 64 bits, so you might want to use casts to uint32_t *,
uint16_t *, and uint8_t * instead of unsigned long *, unsigned short *,
and unsigned char *. The former are guaranteed to be exactly those
sizes, without padding bits and in twos-complement format.
 
C

cr88192

Yep said:
I used this as an example :) I am writing under 32 Bit Pmode in DOS, so
B8000 is correct (sorry for the off topicness), but the code will be used
to control peripherals with their MMAP'd space on the PCI bus.

yes, I was about to comment that one should be sure of this one.
there is always the risk of some or another newb trying to compile something
like this in windows or linux and wondering why it doesn't work...

now, this construct is funky in that it will neither work in a full 32-bit
OS, nor in real-mode, so (raw or DPMI) pmode is needed (taking as an
assumption that there are no compilers targeting big-real mode...).

My bad. I shouldnt have put '' but yes, the value of 3 in binary, not
ascii. But to be technically correct writing a word value of 0x7f50 will
put a capital 'P' in white text on grey background on the screen, a dword
value 0x7f507f50 will put 2 of them as the ordering is attrib,character.

now what is more fun is moving the cursor, and implementing the code for
pulling off the usual scrolling textual display.

actually, interesting and possible is to implement an IRC style interface,
where the commandline is always pinned to the bottom of the screen and text
starts at the bottom and moves up...

of course, the more traditional interface also works fairly well (and is a
little more flexible, and mixes better with our good old friend ANSI control
codes...). actually, at the time I had found a copy of the VT100 manual and
implemented nearly every applicable command...

later on, this project (a hobby OS), ended up using ModeX and VESA in place
of text mode (I think I had also started on a native driver for the S3
Virge...).

one noticable observation at the time was that video memory was a lot slower
than native memory, so it was faster to draw everything in a local buffer
and dump it to the screen (computers were not so fast back then).

eventually this project died because I decided it was pointless.

but, oh well...

There is a reason for it. I need to be able to write explicit 8, 16, 32
bit values to any address within the 32 bit address space. This is allowed
on the platform I am writing (32 Bit Pmode under DOS).

yeah...
 
C

cr88192

santosh said:
I'm not clear about what you are saying above but that line actually
takes the value of myaddress (which is the address it holds) which of
type char * and explicitly converts it to a value of type unsigned
short *, then deferencing this value to write somevalue.


These are the least sizes that the C standard requires but they *could*
be bigger on some platforms. At least on the x86_64 under some OSes
long is actually 64 bits, so you might want to use casts to uint32_t *,
uint16_t *, and uint8_t * instead of unsigned long *, unsigned short *,
and unsigned char *. The former are guaranteed to be exactly those
sizes, without padding bits and in twos-complement format.

now, an x86-64 DPMI would be interesting...

actually, I would have liked it had x86-64 come with some way of using the
extended GPRs and XMM regs in 32-bit mode...

actually, I would have also liked it had existing 64 bit OS's come up with
the idea of running drivers in Ring1 or Ring2 connected to a 32-bit stub
kernel, so that 32-bit drivers would still work in long mode...

or, also, a 64-bit "monitor" kernel, with a 32-bit "main" kernel and
drivers, and a mix of 32 bit and 64 bit processes. most of the OS would
remain 32-bit, but then we can start adding 64 bit stuff...

oh well... drivers will catch up with the OS'es and HW...
 
I

Ian Collins

cr88192 said:
actually, I would have also liked it had existing 64 bit OS's come up with
the idea of running drivers in Ring1 or Ring2 connected to a 32-bit stub
kernel, so that 32-bit drivers would still work in long mode...

or, also, a 64-bit "monitor" kernel, with a 32-bit "main" kernel and
drivers, and a mix of 32 bit and 64 bit processes. most of the OS would
remain 32-bit, but then we can start adding 64 bit stuff...
Considering (at least in the *nix wold) how quickly drivers have been
ported to 64 bit, that would have been wasted effort.

Throw someone a life-line, they'll cling on to it, make them swim and
they'll swim!
 
C

cr88192

Ian Collins said:
Considering (at least in the *nix wold) how quickly drivers have been
ported to 64 bit, that would have been wasted effort.

Throw someone a life-line, they'll cling on to it, make them swim and
they'll swim!

we still have problems in windows land, and when forced to rely on
crufted-over windows drivers...

 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top