OSDev.org
https://forum.osdev.org/

How to print a pointer address in hex?
https://forum.osdev.org/viewtopic.php?f=1&t=32949
Page 1 of 1

Author:  AwfulMint [ Sun May 20, 2018 12:40 pm ]
Post subject:  How to print a pointer address in hex?

I'm starting in os dev and I have in my kernel, functions to print to the terminal, cursor update and serial communication. I'm searching for a long time and nothing :/

I want to know how can I print the address of a pointer to screen and get this address and convert it to a string and send it to my serial port. Plz help me dudes, I'm dumb #-o

Author:  justinian [ Sun May 20, 2018 5:43 pm ]
Post subject:  Re: How to print a pointer address in hex?

Well, first you need to cast the pointer to an appropriately-sized unsigned integer. (uint32_t, or uint64_t on a 64bit cpu in long mode.) Now, every 4 bits of that integer is one hex digit. So to convert it to a string, you can just shift and mask to get just the 4 bits you want, and map that into a static global array of characters ("0123456789abcdef"). To get the number in the right readable direction, make sure you're converting the most significant bits first.

Here's an very simple example from my bootloader.

Author:  AwfulMint [ Sun May 20, 2018 6:20 pm ]
Post subject:  Re: How to print a pointer address in hex?

Ok, I'll try to adapt it to my needs. When casting a common pointer to a uint32_t pointer for example, I can get the common pointer memory address?

I'm searchin ways to debug my kernel, I'm using serial ports bcs I don't know how to make my own printf function.

Author:  AwfulMint [ Sun May 20, 2018 6:59 pm ]
Post subject:  Re: How to print a pointer address in hex?

So I really get strange things, first when trying to convert a pointer to uint32_t pointer not seems to work.

Second thing, what this means: 0000694f00000000

Putting it into an Hex to ASCII I get crazy symbols and iO (yes inverted).

My code:
Code:
const uint16_t digits[] = {
    u'0', u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9', u'a', u'b', u'c', u'd', u'e', u'f'
};

void printHexDigit(uint32_t n) {
    char buffer[9];
    char *p = buffer;

    for (int i = 7; i >= 0; --i) {
   uint8_t nibble = (n & (0xf << (i*4))) >> (i*4);
   *p++ = digits[nibble];
    }
    *p = 0;
    writeStr(SERIAL_COM1, buffer);
}

void kmain(void) {
    Console *console = NULL;
   
    ttyInitialize(console);
   
    writeStr(SERIAL_COM1, "Iniciando log...\n");
    writeStr(SERIAL_COM1, "Aether Kernel v0.01 BUILD 0001, estágio 1 iniciado!\n\n");
   
    uint8_t c[] = {'O', 'i'};
   
    uint32_t *p = (uint32_t*) c;
   
    printHexDigit(p[0]);
    printHexDigit(p[1]);
   
    println(console, "Aether Kernel v0.01 BUILD 0001");
}

Author:  AwfulMint [ Sun May 20, 2018 7:22 pm ]
Post subject:  Re: How to print a pointer address in hex?

Ow there's one more thing, this function convert a string to hex. I want to get the memory location of a pointer and prints it as hex example:

Code:
SomeType *p = ...;

writeHex(*p);


and the out something like: 0xA9924354

Author:  justinian [ Sun May 20, 2018 9:31 pm ]
Post subject:  Re: How to print a pointer address in hex?

AwfulMint wrote:
Code:
const uint16_t digits[] = {
    u'0', u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9', u'a', u'b', u'c', u'd', u'e', u'f'
};


You probably don't want uint16_t for your implementation. In this case I was working with UEFI, which uses wide characters. Unless you're also in UEFI-land, you most likely want just char. (Which also means you don't need the u prefix on your character literals.

AwfulMint wrote:
Code:
    uint8_t c[] = {'O', 'i'};
   
    uint32_t *p = (uint32_t*) c;
   
    printHexDigit(p[0]);
    printHexDigit(p[1]);


Take a step back and think about what you're asking the compiler for with the data types here. Remember than in C, a pointer and an array are not very different. So you're telling the compiler to allocate two bytes on the stack for 'Oi', and c points to those two bytes. You then make p point to the same address, and then ask it to read 4 bytes starting at p as a uint32_t, and then the next 4 bytes after that as a uint32_t, when you only allocated 2 bytes.

What you probably want here is the address of each uint8_t in array c. And you want to convert the address (not the value) to a uint32_t. So instead of casting it as pointer (uint32_t*) you just want to treat it as a value (uint32_t).

You might want to refresh yourself on pointers and datatypes (here's a short tutorial). As for why you see "iO" in the output, it's because you're treating that memory as a 32-bit number on a little-endian computer - what used to be known as the "NUXI" problem on old UNIX machines.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/