2016-09-04 20 views
1

Написал простую программу с большим буфером в сегменте .bssПочему gdb не показывает изменение в массиве BSS при вычислении адреса с тем же выражением, что и режим адресации?

h_vals: 
    resq 99999 

затем попытался увеличивает значение некоторой ячейки массива.

mov rcx, [h_vals+8*rax] 
inc rcx 
mov [h_vals+8*rax], rcx 

Все еще в gdb видят то же значение (0) как до, так и после выполнения третьей инструкции.

x/dg &h_vals &h_vals + 8 * $rax 
0x6d68c0: 0 

Почему я все еще вижу 0, когда пытаюсь проверить адрес, который я хранил?

ответ

2

mov явно передает данные; Ваша программа будет segfault, если она не удалась.

Размер по умолчанию для символов без отладочной информации - 4 байта. Вы можете использовать ptype h_vals, чтобы узнать, что думает о нем gdb.

Помните, что синтаксис gdb работает как C, даже если вы отлаживаете asm. В C, добавляя что-то к смещению указателя этим множеством элементов, а не столько байтов.

&h_vals &h_vals + 8 * $rax не оценивает в gdb на адрес, который вы ожидаете. (Кроме того, я думаю, что &h_vals &h_vals опечатка, а не то, что вы на самом деле бежал.)

Поскольку GDB считает &h_vals является int*, &h_vals + offset будет производить смещение байта 4 * смещение, так же, как h_vals[offset] в C. Таким образом, адрес вы e x amining in gdb на самом деле [h_vals + 8 * 4 * rax].

Другой способ проверки: p /x &h_vals и p /x $rax отдельно. Вы можете самостоятельно выработать математику и сравнить ее с адресом, который вы видели на выходе x/.


Самым безопасным решением здесь является приведение к char*:

x /dg 8 * $rax + (char*)&h_vals 

Или: определить свои символы в .c так что компилятор будет генерировать отладочную информацию для них (потому что дон я не хочу этого делать вручную).

например. поставьте unsigned long h_vals[99999]; в .c, который вы компилируете с помощью gcc -c -g vars.c, и свяжите полученный .o с .o YASM, созданный из вашего .asm. не

+0

PTYPE h_vals типа = <переменных данных, нет отладочной информации> печати & h_vals типа = <переменных данных нет информации отладки> 0x6010c0 печати $ Ракс Он не согласен с 27328 * 8 = 218624 (0x35600), 0x35600 + 0x6010c0 = 0x6366c0 (не 0x6d68c0). –

+0

вы можете использовать 'p/x $ rax' для печати в шестнадцатеричном формате. Похоже, что размер по умолчанию для символов без информации об отладке - 4 байта; который точно соответствует: '(0x6d68c0 - 0x6010c0)/(8 * 27328)' is 4. –

+0

'rax' - 0x6aco (27328 в десятичной системе). Вычисления одинаковы. –