Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When debugging with gdb, what is the meaning of the debugging information in the front of the assembly code?

Tags:

c++

c

gdb

When debugging c code with gdb, the displayed assembly code is

0x000000000040116c main+0 push %rbp
  0x000000000040116d main+1 mov %rsp,%rbp
!0x0000000000401170 main+4 movl $0x0,-0x4(%rbp)
  0x0000000000401177 main+11 jmp 0x40118d <main+33>
  0x0000000000401179 main+13 mov -0x4(%rbp),%eax
  0x000000000040117c main+16 mov %eax,%edx
  0x000000000040117e main+18 mov -0x4(%rbp),%eax

Is the 0x000000000040116d in the front of the first assembly instruction the virtual address of this function? Is main+1 the offset of this assembly from the main function? The next assembly is main+4. Does it mean that the first mov %rsp,%rbp is three bytes? If so, why is movl $0x0,-0x4(%rbp) 7 bytes?

I am using a server. The version is:Linux version 4.15.0-122-generic (buildd@lcy01-amd64-010) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)) #124~16.04.1-Ubuntu SMP.

like image 895
Gerrie Avatar asked Dec 04 '20 01:12

Gerrie


People also ask

Can GDB debug assembly?

gdb will work in an ordinary terminal window, and this is fine for debugging assembly code. For use with higher-level source code, it is more convenient to use gdb from within the emacs editor (a good one to learn!) or using a graphical front-end like ddd.

How do I debug an assembly file?

You start debugging by clicking Start Debugging on the Debug menu. On the Start Debugging dialog box, check Enable Assembler debugging, then click OK. If you debug the module again during the same session, you can start it by clicking Start Debugging, Run or Debug.


Video Answer


1 Answers

Pretty much yes. It's quite apparent that, for example, adding 4 to the first address gives you the address shown for main+4, and adding another 7 on top of that gives you the corresponding address for main+11.

As far as the two move instructions go: they are very different, and do completely different things. They are two very different kind of moves, and that's how many bytes each one requires in x86 machine language, so its not surprising that one takes many more bytes than the other. As far as the precise reason why, well, in general, that opens a very long, broad, and windy discussion about the underlying reasons, and the original design goals of the x86 machine language instruction set. Much of it actually no longer applies (and you would probably find quite boring, actually), since the modern x86 CPU is something quite radically different than its original generation. But it has to remain binary compatible. Hence, little oddities like that.

Just to give you a basic understanding: the first move is between two CPU registers. Doesn't take a long novel to specify from where, and to where. The second move has to specify a 32 bit value (0 to be precise), a CPU register, and a memory offset. That has to be specified somewhere. You have to find the bytes somewhere to specify all the little details for that.

like image 164
Sam Varshavchik Avatar answered Oct 16 '22 11:10

Sam Varshavchik