Help with pointers and absolute memory addresses

Discussion in 'C Programming' started by Ian Collins, Apr 27, 2008.

  1. Ian Collins

    Ian Collins Guest

    Just follow the same pattern,

    T *myaddress = (T*)0xB8000;

    *myaddress = someT;
     
    Ian Collins, Apr 27, 2008
    #1
    1. Advertisements

  2. 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;
     
    Walter Roberson, Apr 27, 2008
    #2
    1. Advertisements

  3. Ian Collins

    Yep Guest

    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.
     
    Yep, Apr 27, 2008
    #3
  4. Ian Collins

    Ian Collins Guest

    Maybe writing the expression as

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

    makes it clearer?
     
    Ian Collins, Apr 27, 2008
    #4
  5. Ian Collins

    Yep Guest

    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.
    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.
    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).
     
    Yep, Apr 27, 2008
    #5
  6. Ian Collins

    Yep Guest

    That works! Why is the extra * needed in front of the cast?
     
    Yep, Apr 27, 2008
    #6
  7. Ian Collins

    Yep Guest

    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!!!!!
     
    Yep, Apr 27, 2008
    #7
  8. Ian Collins

    santosh Guest

    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.
     
    santosh, Apr 27, 2008
    #8
  9. Ian Collins

    cr88192 Guest

    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...).

    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...

    yeah...
     
    cr88192, Apr 27, 2008
    #9
  10. Ian Collins

    cr88192 Guest

    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...
     
    cr88192, Apr 27, 2008
    #10
  11. Ian Collins

    Ian Collins Guest

    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!
     
    Ian Collins, Apr 27, 2008
    #11
  12. Ian Collins

    cr88192 Guest

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

     
    cr88192, Apr 28, 2008
    #12
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.