Plouff
Plouff

Reputation: 31

What is in the address of main?

A simple piece of code like this

#include<stdio.h>
int main()
{

    return 0;
}

check the value in "&main" with gdb,I got 0xe5894855, I wonder what's this?

(gdb) x/x &main
0x401550 <main>:        0xe5894855
(gdb)

Upvotes: 2

Views: 776

Answers (3)

Lundin
Lundin

Reputation: 213513

Ok so the 0x401550 is the address of main() and the hex goo to the right is the "contents" of that address, which doesn't make much sense since it's code stored there, not data.

To explain what that hex goo is coming from, we can toy around with some artificial examples:

#include <stdio.h>

int main (void)
{
  printf("%llx\n", (unsigned long long)&main);
}

Running this code on gcc x86_64, I get 401040 which is the address of main() on my particular system (this time). Then upon modifying the example into some ugly hard coding:

#include <stdio.h>

int main (void)
{
  printf("%llx\n", (unsigned long long)&main);
  printf("%.8x\n", *(unsigned int*)0x401040);
}

(Please note that accessing absolute addresses of program code memory like this is dirty hacking. It is very questionable practice and some systems might toss out an hardware exception if you attempt it.)

I get

401040
08ec8348

The gibberish second line is something similar to what gdb would give: the raw op codes for the instructions stored there.

(That is, it's actually a program that prints out the machine code used for printing out the machine code... and now my head hurts...)

Upon disassembly and generating a binary of the executable, then viewing numerical op codes with annotated assembly, I get:

        main:
         48 83 ec 08
401040   sub    rsp,0x8

Where the 48 83 ec 08 is the raw machine code, including the instruction sub with its parameters (x86 assembler isn't exactly my forte, but I believe 48 is "REX prefix" and 83 is the op code for sub). Upon attempting to print this as if it was integer data rather than machine code, it got tossed around according to x86 little endian ordering from 48 83 ec 08 to 08 ec 83 48. And that's the hex gibberish 08ec8348 from before.

Upvotes: 2

Shane Reilly
Shane Reilly

Reputation: 251

(gdb) x/x &main
0x401550 <main>:        0xe5894855
(gdb)

0xe5894855 is hex opcodes of the first instructions in main, but since you used x/x now gdb is displaying it as just a hex number and is backwards due to x86-64 being little-endian. 55 is the opcode for push rbp and the first instruction of main. Use x/i &main to view the instructions.

Upvotes: 4

John Bollinger
John Bollinger

Reputation: 180103

check the value in "&main" with gdb,I got 0xe5894855, I wonder what's this?

The C expression &main evaluates to a pointer to (function) main.

The gdb command

x/x &main

prints (eXamines) the value stored at the address expressed by &main, in hexadecimal format (/x). The result in your case is 0xe5894855, but the C language does not specify the significance of that value. In fact, C does not define any strictly conforming way even to read it from inside the program.

In practice, that value probably represents the first four bytes of the function's machine code, interpreted as a four-byte unsigned integer in native byte order. But that depends on implementation details both of GDB of the C implementation involved.

Upvotes: 3

Related Questions