Могут ли микросхемы Thumb-2 ARM-Core от разных производителей иметь одинаковый размер?

Сравнение двух микрофонов Thumb-2 от двух разных производителей. Кто-то Cortex M3, кто-то A5. Они гарантированно скомпилируют определенный фрагмент кода с одинаковым размером кода?

1 ответ

Так что здесь идет

fun.c

unsigned int fun ( unsigned int x )
{
    return(x);
}

addimm.c

extern unsigned int fun ( unsigned int );
unsigned int addimm ( unsigned int x )
{
    return(fun(x)+0x123);
}

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

инструкции руки

arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-a5 -march=armv7-a -c addimm.c -o addimma.o

разборка объекта, не связанная

00000000 <addimm>:
   0:   e92d4008    push    {r3, lr}
   4:   ebfffffe    bl  0 <fun>
   8:   e2800e12    add r0, r0, #288    ; 0x120
   c:   e2800003    add r0, r0, #3
  10:   e8bd8008    pop {r3, pc}

универсальный большой палец (armv4 или v5 независимо от значения по умолчанию для этой сборки компилятора)

arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -c addimm.c -o addimmt.o

00000000 <addimm>:
   0:   b508        push    {r3, lr}
   2:   f7ff fffe   bl  0 <fun>
   6:   3024        adds    r0, #36 ; 0x24
   8:   30ff        adds    r0, #255    ; 0xff
   a:   bc08        pop {r3}
   c:   bc02        pop {r1}
   e:   4708        bx  r1

Cortex-A5 специфичный

arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-a5 -march=armv7-a -c addimm.c -o addimma5.o

00000000 <addimm>:
   0:   b508        push    {r3, lr}
   2:   f7ff fffe   bl  0 <fun>
   6:   f200 1023   addw    r0, r0, #291    ; 0x123
   a:   bd08        pop {r3, pc}

cortex-a5 - это armv7-a, который поддерживает thumb-2 в том, что касается самого немедленного добавления, и в связи с размером двоичного файла здесь оптимизации нет, 32 бита для большого пальца и 32 бита для большого пальца 2. Но это всего лишь один пример, возможно, будут времена, когда thumb2 производит меньшие двоичные файлы, чем thumb.

Cortex-M3

arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 -march=armv7-m -c addimm.c -o addimmm3.o

00000000 <addimm>:
   0:   b508        push    {r3, lr}
   2:   f7ff fffe   bl  0 <fun>
   6:   f200 1023   addw    r0, r0, #291    ; 0x123
   a:   bd08        pop {r3, pc}

дал тот же результат, что и Cortex-A5. в этом простом примере машинный код для этого объекта такой же, того же размера, когда построен для cortex-a5 и cortex-m3

Теперь, если я добавлю загрузчик, main и вызову эту функцию и заполню функцию, которую она вызывает, чтобы создать законченную, связанную программу

00000000 <_start>:
   0:   f000 f802   bl  8 <notmain>
   4:   e7fe        b.n 4 <_start+0x4>
    ...

00000008 <notmain>:
   8:   2005        movs    r0, #5
   a:   f000 b801   b.w 10 <addimm>
   e:   bf00        nop

00000010 <addimm>:
  10:   b508        push    {r3, lr}
  12:   f000 f803   bl  1c <fun>
  16:   f200 1023   addw    r0, r0, #291    ; 0x123
  1a:   bd08        pop {r3, pc}

0000001c <fun>:
  1c:   4770        bx  lr
  1e:   46c0        nop         ; (mov r8, r8)

Мы получаем результат. Сама функция addimm не изменилась в размере. с cortex-a5 у вас должен быть код руки, который затем переключается на большой палец, и, вероятно, при соединении с библиотеками и т. д. вы можете получить смесь руки и большого пальца, поэтому

00000000 <_start>:
   0:   eb000000    bl  8 <notmain>
   4:   eafffffe    b   4 <_start+0x4>

00000008 <notmain>:
   8:   e92d4008    push    {r3, lr}
   c:   e3a00005    mov r0, #5
  10:   fa000001    blx 1c <addimm>
  14:   e8bd4008    pop {r3, lr}
  18:   e12fff1e    bx  lr

0000001c <addimm>:
  1c:   b508        push    {r3, lr}
  1e:   f000 e804   blx 28 <fun>
  22:   f200 1023   addw    r0, r0, #291    ; 0x123
  26:   bd08        pop {r3, pc}

00000028 <fun>:
  28:   e12fff1e    bx  lr

в целом больший двоичный файл, хотя сама часть addimm не изменилась в размере.

что касается связывания изменения размера объекта, посмотрите на этот пример

bootstrap.s

.thumb

.thumb_func
.globl _start
_start:
    bl notmain
hang: b hang

.thumb_func
.globl dummy
dummy:
    bx lr

.code 32
.globl bounce
bounce:
    bx lr

Привет

void dummy ( void  );
void bounce ( void  );
void notmain ( void )
{
    dummy();
    bounce();
}

глядя на сборку руки не самого объекта, объекта:

00000000 <notmain>:
   0:   e92d4800    push    {fp, lr}
   4:   e28db004    add fp, sp, #4
   8:   ebfffffe    bl  0 <dummy>
   c:   ebfffffe    bl  0 <bounce>
  10:   e24bd004    sub sp, fp, #4
  14:   e8bd4800    pop {fp, lr}
  18:   e12fff1e    bx  lr

в зависимости от того, что вызывает его и что он вызывает, компоновщику может потребоваться добавить больше кода для работы с элементами, которые определены вне объекта, от глобальных переменных до внешних функций

00008000 <_start>:
    8000:   f000 f818   bl  8034 <__notmain_from_thumb>

00008004 <hang>:
    8004:   e7fe        b.n 8004 <hang>

00008006 <dummy>:
    8006:   4770        bx  lr

00008008 <bounce>:
    8008:   e12fff1e    bx  lr

0000800c <notmain>:
    800c:   e92d4800    push    {fp, lr}
    8010:   e28db004    add fp, sp, #4
    8014:   eb000003    bl  8028 <__dummy_from_arm>
    8018:   ebfffffa    bl  8008 <bounce>
    801c:   e24bd004    sub sp, fp, #4
    8020:   e8bd4800    pop {fp, lr}
    8024:   e12fff1e    bx  lr

00008028 <__dummy_from_arm>:
    8028:   e59fc000    ldr ip, [pc]    ; 8030 <__dummy_from_arm+0x8>
    802c:   e12fff1c    bx  ip
    8030:   00008007    andeq   r8, r0, r7

00008034 <__notmain_from_thumb>:
    8034:   4778        bx  pc
    8036:   46c0        nop         ; (mov r8, r8)
    8038:   eafffff3    b   800c <notmain>
    803c:   00000000    andeq   r0, r0, r0

Оба dummy_from_arm и notmain_from_thumb были добавлены, увеличив размер двоичного файла. каждый объект не изменился в размере, но общий двоичный файл изменился. bounce() был функцией "рука-рука", без патчей, dummy() рука для большого пальца и notmain() для большого пальца.

таким образом, у вас может быть объект cortex-m3 и объект cortex-a5, которые по отношению к коду в этом объекте идентичны. Но в зависимости от того, с чем вы их связываете, что в конечном итоге что-то не так между системой cortex-m3 и системой cortex-a5, вы можете увидеть более или менее код, добавленный компоновщиком для учета системных различий, библиотек, конкретной операционной системы. и т. д. Даже в том случае, когда в двоичный файл вы помещаете объект, если он должен иметь более широкий охват, чем он может получить с помощью одной инструкции, компоновщик добавит еще больше кода.

Это все специфичные для gcc вещи, каждая цепочка инструментов будет решать каждую из этих проблем по-своему. Это характер зверя, когда вы используете модель объекта и компоновщика, очень хорошая модель, но компилятор, ассемблер и компоновщик должны работать вместе, чтобы обеспечить правильный доступ к глобальным ресурсам при компоновке. не имеет ничего общего с ARM, эта проблема существует во многих / большинстве процессорных архитектур, и цепочки инструментов решают эти проблемы для каждой цепочки инструментов, для версии, для целевой архитектуры. Когда я сказал "изменить размер объекта", я действительно имел в виду, что компоновщик может добавить больше кода в конечный двоичный файл, чтобы иметь дело с этим объектом и его взаимодействием с другими.

Другие вопросы по тегам