The directive
asm("movl 4(%%ebp),%0;" : "=r"(VAR));
copies a 32-bit quantity from [EBP+4]
to VAR
. VAR
in your case is defined as calladdr
. This assumes that the return address is 32-bit, which is not true anymore in a 64-bit system, and it assumes that the return address is at [EBP+4]
, which is also not true anymore in a 64-bit system.
The reason why it fails is that calladdr
is something like [EBP-x]
(where x is some number like 4,) and there is no single Intel x86 instruction that will both fetch from [EBP+4]
and store at [EBP-x]
, so the value fetched from [EBP+4]
must be stored in some register, and then the value of that register must be stored at [EBP-x]
. Then for some unknown to me reason gcc decides to use register rax
for this job, but rax
is 64-bit wide, while the 'l' prefix of the movl
instruction implies a 32-bit quantity, so there is a mismatch.
Even if you somehow managed to sort this out, your next problem would be that on a 64-bit architecture, the return address is not at [EBP+4]
.
So, this entire clause is an assumption that you are in 32-bits.
My recommendation: completely ditch this nonsense and replace it with some ready-made library (no need to re-invent the wheel) that works both in 32-bit and 64-bit mode, or with gcc's built-in function for retrieving the return address, as suggested by Michael Petch; then proceed to rebuild in 64-bit like a boss.