C++ – How to see the assembly code for a C++ program
assemblycdisassembly
How can I see the assembly code for a C++ program?
What are the popular tools to do this?
Best Answer
Ask the compiler
If you are building the program yourself, you can ask your compiler to emit assembly source. For most UNIX compilers use the -S switch.
If you are using the GNU assembler, compiling with -g -Wa,-alh will give intermixed source and assembly on stdout (-Wa asks compiler driver to pass options to assembler, -al turns on assembly listing, and -ah adds "high-level source" listing):
int x = 5;
int y = 6;
int *p;
p = &x;
p = &y;
*p = 10;
assert(x == 5);
assert(y == 10);
A reference cannot be re-bound, and must be bound at initialization:
int x = 5;
int y = 6;
int &q; // error
int &r = x;
A pointer variable has its own identity: a distinct, visible memory address that can be taken with the unary & operator and a certain amount of space that can be measured with the sizeof operator. Using those operators on a reference returns a value corresponding to whatever the reference is bound to; the reference’s own address and size are invisible. Since the reference assumes the identity of the original variable in this way, it is convenient to think of a reference as another name for the same variable.
int x = 0;
int &r = x;
int *p = &x;
int *p2 = &r;
assert(p == p2); // &x == &r
assert(&p != &p2);
You can have arbitrarily nested pointers to pointers offering extra levels of indirection. References only offer one level of indirection.
int x = 0;
int y = 0;
int *p = &x;
int *q = &y;
int **pp = &p;
**pp = 2;
pp = &q; // *pp is now q
**pp = 4;
assert(y == 4);
assert(x == 2);
A pointer can be assigned nullptr, whereas a reference must be bound to an existing object. If you try hard enough, you can bind a reference to nullptr, but this is undefined and will not behave consistently.
/* the code below is undefined; your compiler may optimise it
* differently, emit warnings, or outright refuse to compile it */
int &r = *static_cast<int *>(nullptr);
// prints "null" under GCC 10
std::cout
<< (&r != nullptr
? "not null" : "null")
<< std::endl;
bool f(int &r) { return &r != nullptr; }
// prints "not null" under GCC 10
std::cout
<< (f(*static_cast<int *>(nullptr))
? "not null" : "null")
<< std::endl;
You can, however, have a reference to a pointer whose value is nullptr.
Pointers can iterate over an array; you can use ++ to go to the next item that a pointer is pointing to, and + 4 to go to the 5th element. This is no matter what size the object is that the pointer points to.
A pointer needs to be dereferenced with * to access the memory location it points to, whereas a reference can be used directly. A pointer to a class/struct uses -> to access its members whereas a reference uses a ..
References cannot be put into an array, whereas pointers can be (Mentioned by user @litb)
Const references can be bound to temporaries. Pointers cannot (not without some indirection):
const int &x = int(12); // legal C++
int *y = &int(12); // illegal to take the address of a temporary.
This makes const & more convenient to use in argument lists and so forth.
Best Answer
Ask the compiler
If you are building the program yourself, you can ask your compiler to emit assembly source. For most UNIX compilers use the
-S
switch.If you are using the GNU assembler, compiling with
-g -Wa,-alh
will give intermixed source and assembly on stdout (-Wa
asks compiler driver to pass options to assembler,-al
turns on assembly listing, and-ah
adds "high-level source" listing):g++ -g -c -Wa,-alh foo.cc
For Visual Studio, use
/FAsc
.Peek into a binary
If you have a compiled binary,
objdump -d a.out
on UNIX (also works for cygwin),dumpbin /DISASM foo.exe
on Windows.Use your debugger
Debuggers could also show disassembly.
disas
command in GDB.Use
set disassembly-flavor intel
if you prefer Intel syntax.