Почему адреса в дампе моего ассемблера отличаются от адресов регистров? - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть очень простая программа, которую я скомпилировал с

gcc -m32 -g -o hello32.out hello.c

Когда я запускаю дизассемблирование main в gdb, я получаю следующий вывод:

0x0000051d <+0>:    lea    ecx,[esp+0x4]
0x00000521 <+4>:    and    esp,0xfffffff0
0x00000524 <+7>:    push   DWORD PTR [ecx-0x4]
0x00000527 <+10>:   push   ebp
0x00000528 <+11>:   mov    ebp,esp
0x0000052a <+13>:   push   ebx
0x0000052b <+14>:   push   ecx
0x0000052c <+15>:   sub    esp,0x10
0x0000052f <+18>:   call   0x420 <__x86.get_pc_thunk.bx>
0x00000534 <+23>:   add    ebx,0x1aa4
0x0000053a <+29>:   mov    DWORD PTR [ebp-0xc],0x0
... [truncated for brevity]

Однако, когда я запускаю

(gdb) break main
(gdb) run
(gdb) info register eip

Я получаю

eip            0x5655553a   0x5655553a <main+29>

Почему main + 29 отображается как 0x0000053a в дампе ассемблера, а 0x5655553a, когда указан адрес eip?

1 Ответ

0 голосов
/ 15 ноября 2018

Ваш GCC делает исполняемые файлы PIE по умолчанию, поэтому в файле нет фиксированного базового адреса (и разборка показывает его относительно 0, то есть смещений, а не абсолютных адресов).

Как только загрузчик программ ELF ядра создал запущенный процесс из исполняемого файла (и выбрал виртуальный адрес в качестве базы), GDB может показать вам фактические виртуальные адреса времени выполнения.

Сборка с -fno-pie -no-pie для получения зависимых от позиции исполняемых файлов , где адрес времени выполнения известен из исполняемых метаданных. (Вы определенно должны предпочесть -fno-pie для кода i386: без RIP-относительной адресации дополнительная производительность / размер кода для кода, независимого от позиции, значительно хуже, чем для x86-64.)


Связанные: 32-разрядные абсолютные адреса больше не разрешены в x86-64 Linux? для получения дополнительной информации о PIE (как 32-разрядных, так и 64-разрядных x86 и вообще.)

GDB - адрес точки останова аналогичен этому, но не совсем дубликат.

...