Reputation: 1506
I am reading a C book that deals a lot with asm and looking at registers and memory with GDB. The issue is, when I compile and disassemble the exact same source (actually using the source files that came WITH the book cd), the assembly instructions look quite a bit different than what's in the book. The book uses intel flavored assembly and I am putting "set disassembly intel" in gdb, so it's not that.. just the instructions are in different order, some are all together different, and there are a few other quirks.
For instance, in the book there is a mov instruction in the eip register:
(gdb) x/i $eip
mov DWORD PTR[ebp-4], 0x0
corresponding to initializing the variable i to 0, in a for loop (i = 0, i<10, i++)
However, in my gdb console, with the breakpoint at the same place (set break main; run) I see this:
(gdb) x/i $eip
mov DWORD PTR[esp+0x1c], 0x0
notice it's referencing a different register all together - esp instead of ebp if I check the value of esp, it's 0x1c itself. But if I try examine what's at 0x1c, or at esp+0x1c, it tells me that I am not able to look at those addresses
So as the book goes on, I can't follow along at all, because it starts following the trail of what's in ebp, ebp-4, and so on, and in my asm there doesn't seem to be anything happening with the ebp register
The book was written in 2008, so I can't imagine its so out of date that a version change of gcc or gdb would introduce that significant of a change (or did it?)... is it possible there is some compiler optimization or something switched on by default that is producing such different results?
Thanks in advance
Edit: Strange. I tried each of the suggestions and nothing worked. Then I did rm a.out and recompiled fresh and now it works fine (the instructions are different than the book still but I can examine the address corresponding to that of the book; as long as I can follow a corresponding pattern all is well, doesn't have to be the exact same asm, that would just make it too easy!) Thanks again for all your help and suggestions.
Upvotes: 0
Views: 504
Reputation: 213375
It looks like the code you compiled was compiled with -fomit-frame-pointers
, which became the default with GCC-4.6.
Try building with explicit -fno-omit-frame-pointer
. I expect the results will look much closer to the book.
Upvotes: 1
Reputation: 48765
There are a million things that could cause this. If you compiled your code on a different architecture, I'd expect this (and no, that doesn't even necessarily mean 32 vs 64 bit -- literally any different CPU architecture at all can change the execution order as I'll explain). If you compile your programs with optimizations, it will change the ordering of the execution to best exploit your CPU's pipeline. This may mean adding some NOOP instructions, or re-ordering them entirely (within reason, of course). Futhermore some CPUs have multiple ways of doing things, one way usually being faster than the other (the intel LOOP instruction comes to mind -- modern compilers avoid this instruction like the plague because it's terrible). If one register is more efficient than another, it will use it.
The moral of the story: for learning purposes both the author and the reader need to have all optimizations disabled. Also for added bonus points: use the same version of gcc and the same platform.
Upvotes: 1
Reputation: 182743
This is all going to be very platform and compiler specific. I'm afraid there's no much you can do.
Upvotes: 0