параметры компилятора arm-linux-gnueabi

Я использую arm-linux-gnueabi-gcc для компиляции программ C для процессора ARM в Linux. Однако я не уверен, что такое режим ARM по умолчанию, для которого он компилируется.

Например, для кода C:

тест.с

unsigned int main()
{
    return 0x1ffff;
}

arm-linux-gnueabi-gcc -o test test.c

теперь, когда я смотрю на разборку функции main() с помощью objdump, я вижу:

arm-linux-gnueabi-objdump -d test

<main>:

    push    {r7}
    add r7, sp, #0
    movw    r3, #65535  ; 0xffff
    movt    r3, #1
    mov r0, r3
    mov sp, r7
    pop {r7}
    bx  lr

похоже, что это дизассемблирование для режима Thumb ARM (из-за инструкции push).

Как я могу отобразить разборку следующим образом:

      .sect ".text"
      .global _fn
_fn:  MOVW A1,#65535
      MOVT A1,#1

      BX LR

или это

      .sect ".text"
      .global _fn
_fn:  LDR A1, CON1
      BX LR

      .sect ".text"
      .align 4
CON1: .word 0x1ffff

Я видел этот пример здесь:

http://e2e.ti.com/support/development_tools/compiler/f/343/t/40580.aspx

однако я не могу просмотреть разборку так, как она там отображается.

Спасибо.


person Neon Flash    schedule 20.08.2013    source источник


Ответы (2)


push не обязательно скажу вам, что это в режиме большого пальца, на самом деле новый синтаксис сборки ARM называется unified assembly language, что означает, что в большинстве случаев вы можете скомпилировать один и тот же код в наборы инструкций arm или thumb-2.

Другая проблема заключается в том, что вы компилируете в режиме -O0, который добавляет некоторые дополнительные инструкции для облегчения отладки. Попробуйте -O2, и вы должны получить желаемый поток инструкций.

gcc с переключателем -v, как в arm-linux-gnueabi-gcc -v, должно показать вам, как он построен, что также говорит вам об общих параметрах по умолчанию, которые он использует при компиляции вашего исходного кода.

И последнее, упомянутая вами целевая последовательность сборки использует схему именования регистров ATPCS (см. objdump doc для информации), он использует, например, a1 вместо r0. Вы также можете получить это, установив disassembler-options в objdump с переключателем -M. Как показано ниже;

$ arm-linux-gnueabihf-gcc -c -O2 -o test test.c
$ arm-linux-gnueabihf-objdump -M reg-names-special-atpcs -d test

test:     file format elf32-littlearm


Disassembly of section .text.startup:

00000000 <main>:
   0:   f64f 70ff   movw    a1, #65535  ; 0xffff
   4:   f2c0 0001   movt    a1, #1
   8:   4770        bx  LR
   a:   bf00        nop

Другой вариант — получить выходные данные сборки из самого gcc с помощью переключателя -S. Как показано ниже;

$ arm-linux-gnueabihf-gcc -S test.c

затем вы должны получить новый файл с именем test.s в той же папке. Однако я не знаю, есть ли у вас возможность установить имя регистра.

person auselen    schedule 20.08.2013
comment
Спасибо :) Я понял. Кроме того, вы обратили внимание на второй пример дизассемблирования, который я упомянул выше? В этом случае вместо перемещения значения в регистр A1 он загружает значение из константы CON1. Кроме того, при дизассемблировании не упоминаются различные ключевые слова, такие как .global, .align, .word. - person Neon Flash; 20.08.2013
comment
Я обновил ответ, чтобы добавить еще один способ создания сборки, где вы можете играть, чтобы получить результат, аналогичный примеру, которым вы поделились. Другое дело, что вы не заметили, что они упоминают компилятор TI C/C++. Они, вероятно, получили вывод сборки от этого компилятора. - person auselen; 20.08.2013

Я считаю, что по умолчанию используется режим большого пальца:

arm-linux-gnueabi-gcc -S -mthumb test.c

Полные инструкции ARM можно сгенерировать с помощью флага -marm:

arm-linux-gnueabi-gcc -S -marm test.c
person Andy Fusniak    schedule 09.03.2014