g ++ анализ двоичного вывода

Учитывая следующую программу:

unsigned char g1[] = { 0x1a, 0x2a, 0x3a, 0x4a };
static unsigned char g2[] = { 0x1b, 0x2b, 0x3b, 0x4b };

int main()
{
  unsigned char l1[] = { 0x1c, 0x2c, 0x3c, 0x4c };
  static unsigned char l2[] = { 0x1d, 0x2d, 0x3d, 0x4d };
}

После компиляции его просто с помощью «g ++ test.cpp -o test» и запуска hexdump -C на двоичном файле я понял, что последовательности для g1, g2 и l2 можно четко найти в двоичном файле. Только последовательность для l1 (1c 2c 3c 4c), по-видимому, не присутствует нигде в двоичном файле.

Кто-нибудь знает, почему это так?


person user1983801    schedule 16.01.2013    source источник
comment
Почему кто-то отклонил этот вопрос. Я считаю, что это очевидный вопрос.   -  person Grijesh Chauhan    schedule 16.01.2013


Ответы (3)


Потому что он размещен в стеке вызова этой функции. Обычно в таких случаях происходит одно из двух:

  1. Компилятор сохранит эту последовательность в разделе данных, а затем сохранит ее в буфере стека.

  2. Компилятор, по сути, жестко кодирует инструкции «перемещения», чтобы повторно собрать последовательность из наибольшего непосредственного значения набора инструкций (часто 4-байтового int).

Если он не был оптимизирован, как упоминалось в «раскручивании», то, вероятно, происходит №2. Глядя на разборку, программа (или предварительно собранный asm-код) покажет вам лучше. Используйте -S и просмотрите файлы .s.

person Jonathon Reinhart    schedule 16.01.2013

Я предполагаю, что, поскольку он не static и автоматический (неглобальный), тривиально знать, что никто не сможет ссылаться на него извне. Поскольку он не используется, его можно отбросить.

person unwind    schedule 16.01.2013

l1[] и l2[] удаляются во время оптимизации компилятора, потому что оба local and unused variables (нет шансов, что обе переменные будут использоваться где-то еще).

вы можете скомпилировать свой код с опцией -S для генерации кода сборки: и нет определения для l1[] и l2[] в основном, даже где-либо еще:

входной файл был x.c, скомпилирован с помощью команды gcc -S x.c для создания файла сборки x.s

main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movb    $28, -4(%ebp)
    movb    $44, -3(%ebp)
    movb    $60, -2(%ebp)
    movb    $76, -1(%ebp)
    leave
    ret
    .size   main, .-main
    .data
    .type   l2.1250, @object
    .size   l2.1250, 4

Но вы можете найти определение для g1[] and g2[].

    .file   "x.c"
.globl g1
    .data
    .type   g1, @object
    .size   g1, 4
g1:
    .byte   26
    .byte   42
    .byte   58
    .byte   74
    .type   g2, @object
    .size   g2, 4
g2:
    .byte   27
    .byte   43
    .byte   59
    .byte   75
    .text
.globl main
    .type   main, @function  

Кроме того. Было бы интересно узнать, компилируете ли вы код, если компилируете код с флагом -O3 уровень флага оптимизации 3, тогда присутствует только определение g1[]. и глобальные статические переменные (частные для файла) также удаляются.

входной файл был x.c, скомпилирован с помощью команды gcc -S -O3 x.c для создания файла сборки x.s

ниже:

    .file   "x.c"
    .text
    .p2align 4,,15
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    popl    %ebp
    ret
    .size   main, .-main
.globl g1
    .data
    .type   g1, @object
    .size   g1, 4
g1:
    .byte   26
    .byte   42
    .byte   58
    .byte   74
    .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
    .section    .note.GNU-stack,"",@progbits  

g1[] - это только глобальные данные, а g2[] удален в -O3.

g2[] использовать определенные static unsigned char g2[], поэтому доступ только к этому файлу, а не использование, поэтому снова не используется. Но g1[] глобален, он может быть полезен другой программой, если другой файл включает это. И компилятор не может оптимизировать глобальные объекты.

Ссылка: Как предотвратить мои «неиспользованные» компилируются глобальные переменные?

Итак, все благодаря оптимизации компилятора!

person Grijesh Chauhan    schedule 16.01.2013
comment
Думаю, вы можете найти более подробную информацию здесь Методы кодирования, которые позволяют компилятору / оптимизатору создавать более быстрые программы Но я не уверен. Я не читал. - person Grijesh Chauhan; 16.01.2013