Могут ли микросхемы 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, эта проблема существует во многих / большинстве процессорных архитектур, и цепочки инструментов решают эти проблемы для каждой цепочки инструментов, для версии, для целевой архитектуры. Когда я сказал "изменить размер объекта", я действительно имел в виду, что компоновщик может добавить больше кода в конечный двоичный файл, чтобы иметь дело с этим объектом и его взаимодействием с другими.