Как оставить память неинициализированной в сборке GNU ARM? - PullRequest
0 голосов
/ 04 апреля 2019

Я использую GCC на моем Raspberry Pi, чтобы скомпилировать некоторый ассемблерный код для курса, который я беру. Насколько я понимаю из информации в GNU Assembler Reference , я могу воспроизвести следующий код C в сборке GNU ARM:

int num = 0;

Написав это:

        .data
num:    .word 0

Отлично! Теперь, как бы я написал это?

int num;

Насколько я понимаю, если оставить переменную неинициализированной, как это, я должен рассматривать ее как содержащую любое значение мусора, которое ранее находилось в ячейке памяти. Поэтому я не должен использовать его, прежде чем я каким-либо образом определю его значение.

Но предположим, что по какой-то причине я намеревался хранить огромное количество данных в памяти, и мне нужно было зарезервировать для этого огромное количество места. Мне кажется, что было бы огромной тратой ресурсов на инициализацию всей области памяти до некоторого значения, если я все равно собираюсь заполнить ее некоторыми данными. Однако из того, что я могу найти, кажется, нет никакого способа сделать ярлык в ARM Assembly GCC без инициализации его какой-либо ценности. Согласно моему учебнику по сборке директива .word может иметь нулевые выражения после нее, но если использовать ее таким образом, "тогда счетчик адресов не будет расширен и никакие байты не зарезервированы". Сначала я использовал вместо этого директивы ".space" или ".skip", но для этой директивы даже в официальной документации говорится, что "если запятая и заполнение опущены, предполагается, что fill равен нулю . "

Не могу ли я зарезервировать кусок памяти, не инициализировав его в GCC ARM Assembly?

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Что случилось, когда вы попробовали это?

Когда я попробовал это:

int num = 0;
int mun;

с GNU, я получил

    .cpu arm7tdmi
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 1
    .eabi_attribute 30, 2
    .eabi_attribute 34, 0
    .eabi_attribute 18, 4
    .file   "so.c"
    .text
    .comm   mun,4,4
    .global num
    .bss
    .align  2
    .type   num, %object
    .size   num, 4
num:
    .space  4
    .ident  "GCC: (GNU) 8.3.0"

.comm символ,length

.comm объявляет общий символ с именем symbol.При связывании общий символ в одном объектном файле может быть объединен с определенным или общим символом с тем же именем в другом объектном файле.Если ld не видит определения для символа - только один или несколько общих символов - тогда он выделит байты длины неинициализированной памяти.длина должна быть абсолютным выражением.Если ld видит несколько общих символов с одним и тем же именем, и они не все имеют одинаковый размер, он выделяет пространство с наибольшим размером.

При использовании ELF директива .comm принимает необязательный третий аргумент.Это желаемое выравнивание символа, заданное в виде границы байта (например, выравнивание 16 означает, что младшие 4 бита адреса должны быть равны нулю).Выравнивание должно быть абсолютным выражением, и оно должно быть степенью двойки.Если ld выделяет неинициализированную память для общего символа, он будет использовать выравнивание при размещении символа.Если выравнивание не указано, то будет установлено выравнивание с наибольшей степенью двойки, меньшей или равной размеру символа, но не более 16.

Синтаксис для .comm немного отличается вHPPA.Синтаксис: символ. Comm, длина;символ необязательный.

Язык ассемблера определяется ассемблером, а не целью.Таким образом, ответ будет определяться ассемблером (инструментом, который читает и собирает программы на языке ассемблера), и нет никаких оснований предполагать, что ответ для одного ассемблера такой же, как у другого.Вышесказанное относится к ассемблеру gnu, газ.

Вы могли посмотреть документацию, на которую вы ссылались, или прочитать другую документацию по gnu.но самый простой способ ответить на вопрос, что происходит, когда вы делаете это в скомпилированной программе, - просто скомпилировать ее и посмотреть на вывод компилятора.

Но не обязательно предполагать, что он не инициализирован:

unsigned int num;
unsigned int fun ( void )
{
    return(num);
}

достаточно, чтобы связать его:

Disassembly of section .text:

00001000 <fun>:
    1000:   e59f3004    ldr r3, [pc, #4]    ; 100c <fun+0xc>
    1004:   e5930000    ldr r0, [r3]
    1008:   e12fff1e    bx  lr
    100c:   00002000    andeq   r2, r0, r0

Disassembly of section .bss:

00002000 <__bss_start>:
    2000:   00000000

он заканчивается инициализацией bss.

вы действительно хотите неинициализированный доступ к чему-то, а затем просто выберите адрес (который, как вы знаете, не инициализирован (sram)) и получить к нему доступ:

ldr r0,=0x1234
ldr r0,[r0]
1 голос
/ 04 апреля 2019

Как правило, данные, которые вам не нужно инициализировать, должны быть помещены в раздел .bss.

    .bss
foobar:
    .skip 99999999

Это выделит 99999999 байт в секции .bss, а метка foobar будет ее адресом. Это не увеличит ваши объектные файлы или исполняемые файлы на 99999999 байт; исполняемый заголовок просто указывает, сколько байтов .bss необходимо, и во время загрузки система выделяет соответствующее количество и инициализирует его нулем.

Вы не можете пропустить инициализацию нуля во время загрузки. Система должна инициализировать это чем-то, потому что в противном случае она может содержать конфиденциальные данные из ядра или какого-либо другого процесса. Но обнуление памяти происходит довольно быстро, и ядро ​​будет использовать эффективный алгоритм, поэтому я не буду беспокоиться о влиянии на производительность. Он может даже обнулять страницы во время простоя, так что когда ваша программа загружается, там уже обнуленная память уже доступна. В любом случае, время, которое ваша программа тратит на самом деле, используя память, забьет ее.

Это означает, что вы также можете безопасно использовать .bss для данных, которые вы хотите инициализировать на ноль (но не на любое ненулевое значение; если вы хотите int foo = 3;, вам придется поместить его в .data как в вашем первоначальном примере.).

...