The following example is provided in this book.
There are two .c
files and one .h
file.
#include "function.h"
extern int nCompletionStatus;
int main(int argc, char* argv[])
{
float x = 1.0;
float y = 5.0;
float z;
z = add_and_multiply(x,y);
nCompletionStatus = 1;
return 0;
}
#pragma once
#define FIRST_OPTION
#ifdef FIRST_OPTION
#define MULTIPLIER (3.0)
#else
#define MULTIPLIER (2.0)
#endif
float add_and_multiply(float x, float y);
#include "function.h"
int nCompletionStatus = 0;
float add(float x, float y)
{
float z = x + y;
return z;
}
float add_and_multiply(float x, float y)
{
float z = add(x,y);
z *= MULTIPLIER;
return z;
}
To produce the .o
files, the following command is provided:
gcc -c function.c main.c
Then, to view the contents of main.o
, we have:
objdump -D -M intel main.o
.
The author in his book lists the (snippets of) content of the objdump
output thus focussing on the unresolved external reference in main.o
to add_and_multiply(,)
and the extern
ed nCompletionStatus
:
27: 89 04 24 mov DWORD PTR [esp],eax
2a: e8 fc ff ff ff call 2b <main + 0x2b> ;//highlighted (a) by author
2f: d9 5c 24 1c fstp DWORD PTR [esp+0x1c]
33: c7 05 00 00 00 00 01 mov DWORD PTR ds:0x0,0x1 ;//highlighted (b) by author
On my machine, which is slightly different from what the author has produced, I get the following output of objdump
(relevant parts only):
3c: e8 00 00 00 00 call 41 <main+0x41>;//Equivalent to highlight (a) of author?
41: 66 0f 7e c0 movd eax,xmm0
45: 89 45 fc mov DWORD PTR [rbp-0x4],eax
48: c7 05 00 00 00 00 01 mov DWORD PTR [rip+0x0],0x1 # 52 <main+0x52>;//equivalent to highlight (b) of author?
My questions are indicated as comments above. That is, how is the output on my machine (running gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
) equivalent to what the author reports?
In particular, in the author's version, in highlight (b), ds:
seems to be accessed, while in my version, some offset from the rip
register seems to be in place. How are they equivalent?
The book you refer to is using 32 bit assembly while your compiler emits 64 bit assembly. Pass -m32
to gcc
to compile your C code into 32 bit machine code instead. Also consider using -d
instead of -D
for objdump
as the former only tries to disassemble sections that are known to contain machine code.