Понимание ассемблерных инструкций в базовой C-программе в GDB - PullRequest
3 голосов
/ 19 апреля 2019

Пытаясь понять структуру памяти в процессе и изучить ассемблер, я написал базовую программу на C на Pi3 (ARM) и разобрал ее с помощью GDB, но, поскольку я новичок в этом, мне нужна помощь в ее понимании.

По сути, я пытаюсь понять и определить в сборке, где хранятся переменные (сегменты памяти BSS, DATA, TEXT), а также понять и следовать кадрам стека.

Я только отображал основную функцию - на экране отладки были другие сегменты, поэтому дайте мне знать, если они тоже помогут!

Я понимаю, что в основном делают отдельные инструкции, но я хотел бы знать:

  1. Первые 3 строки касаются указателя стека, это настройка фрейма стека для основной функции?

  2. В x0x10414 он использует значение для возраста, это где локальная переменная помещается в стек как часть кадра для основной функции?

  3. В x0x1041c это возвращаемое значение, как я и предполагал, тоже было помещено в стек как часть кадра?

  4. Где стек сбрасывается в конце функции?

int main () {
        int age = 30;
        int salary;
        return 0;
}
0x10408 <main>                  push   {r11}           ; (str r11, [sp, #-4]!)
x0x1040c <main+4>               add    r11, sp, #0                           
x0x10410 <main+8>               sub    sp, sp, #12                           
x0x10414 <main+12>              mov    r3, #30                               
x0x10418 <main+16>              str    r3, [r11, #-8]                        
x0x1041c <main+20>              mov    r3, #0                                
x0x10420 <main+24>              mov    r0, r3                                
x0x10424 <main+28>              add    sp, r11, #0                           
x0x10428 <main+32>              pop    {r11}           ; (ldr r11, [sp], #4) 
x0x1042c <main+36>              bx     lr   

1 Ответ

3 голосов
/ 19 апреля 2019
  1. Да, вы правы. Регистр r11 используется в качестве указателя кадра. Этот указатель кадра служит ссылкой на то, где ваши локальные переменные хранятся в стеке. Обратите внимание, что оригинальный указатель кадра от вызывающей стороны должен быть сохранен (поэтому он сохраняется и восстанавливается позже).
  2. Почти. Это происходит на одну строку позже, он сохраняет его в стеке в [r11 - 8]. Помните, что r11 является указателем кадра, все относительно и относительно этого.
  3. Не помещается в стек. Он просто возвращается в регистр r0. На многих платформах часто используется регистр общего назначения. Тогда стек не нужно использовать для простых и простых возвращаемых значений (например, вашего целого числа). Я полагаю, это из соображений производительности, поскольку регистры работают быстрее, чем доступ к памяти.
  4. Я не знаю, что ты имеешь в виду под флешем Здесь происходит то, что функция настраивает все так, как ей нравится, и впоследствии отменяет эти изменения. Содержимое стека может по-прежнему содержать значения, используемые функцией. Просто указатели сбрасываются в исходное местоположение. Сначала в начале функции указатель исходного кадра (r11) сохраняется / помещается в стек. Тогда значение указателя стека становится указателем нового кадра. В конце функции указатель стека возвращается туда, где он был (перезаписывая его с помощью r11), и, наконец, сам r11 восстанавливается также путем выталкивания его из стека.
...