Сборка ARM не работает без макроса .type - PullRequest
1 голос
/ 17 апреля 2020

Я изучаю некоторый (ARMv6-M) ассемблер для микроконтроллера STM32F0 (ARM Cortex M0). Для начала я написал скрипт, в котором я инициализирую регистр от r0 до 0 и r1 до 1, наконец, r0 увеличивается на 1 в al oop. Используя отладчик, то есть gdb, я могу использовать si для выполнения одного шага и info reg для вывода регистров. Код ассемблера приведен ниже,

.syntax unified
.cpu cortex-m0
.fpu softvfp
.thumb

.global vector_table
.global reset_handler

.type vector_table, %object
vector_table:
    .word _estack
    .word reset_handler

.type reset_handler, %function
reset_handler:
    LDR r0, =0
    LDR r1, =1

    main_loop:
        ADDS r0, r0, 1
    B main_loop

и основан на этом превосходном учебном пособии .

Когда я удаляю макросы .type x, я не вижу любые изменения в регистрах через мои отладчики, однако в соответствии с этот постэкс-стека .type -macro не должен иметь никакого эффекта.

Почему регистр r0 и r1 остаются неизменными, когда я удаляю .type -макрос?

1 Ответ

3 голосов
/ 18 апреля 2020
.syntax unified
.cpu cortex-m0
.fpu softvfp
.thumb

.global vector_table
.global reset_handler

.type vector_table, %object
vector_table:
    .word 0x20001000
    .word reset_handler

.type reset_handler, %function
reset_handler:
    LDR r0, =0
    LDR r1, =1

с функцией .type

Disassembly of section .text:

00001000 <vector_table>:
    1000:   20001000    andcs   r1, r0, r0
    1004:   00001009    andeq   r1, r0, r9

00001008 <reset_handler>:
    1008:   4800        ldr r0, [pc, #0]    ; (100c <reset_handler+0x4>)
    100a:   4901        ldr r1, [pc, #4]    ; (1010 <reset_handler+0x8>)
    100c:   00000000    andeq   r0, r0, r0
    1010:   00000001    andeq   r0, r0, r1

таблица векторов для сброса имеет правильный адрес ORRed с 1 0x1009. Если вы удалите объявление функции

disassembly of section .text:

00001000 <vector_table>:
    1000:   20001000    andcs   r1, r0, r0
    1004:   00001008    andeq   r1, r0, r8

00001008 <reset_handler>:
    1008:   4800        ldr r0, [pc, #0]    ; (100c <reset_handler+0x4>)
    100a:   4901        ldr r1, [pc, #4]    ; (1010 <reset_handler+0x8>)
    100c:   00000000    andeq   r0, r0, r0
    1010:   00000001    andeq   r0, r0, r1

, вы получите двоичный файл, который не будет загружаться в cortex-m. для большого пальца вы также можете использовать .thumb_fun c и следующий найденный ярлык будет считаться функцией

.thumb_func
reset_handler:
    LDR r0, =0
    LDR r1, =1

, и вы снова в порядке, двоичный файл будет работать

so.elf:     file format elf32-littlearm


Disassembly of section .text:

00001000 <vector_table>:
    1000:   20001000    andcs   r1, r0, r0
    1004:   00001009    andeq   r1, r0, r9

00001008 <reset_handler>:
    1008:   4800        ldr r0, [pc, #0]    ; (100c <reset_handler+0x4>)
    100a:   4901        ldr r1, [pc, #4]    ; (1010 <reset_handler+0x8>)
    100c:   00000000    andeq   r0, r0, r0
    1010:   00000001    andeq   r0, r0, r1

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

.syntax unified
.cpu arm7tdmi
.thumb

.global vector_table
.global reset_handler

.type vector_table, %object
vector_table:
    .word 0x20001000
    .word reset_handler

.thumb_func
reset_handler:
    LDR r0, =0
    LDR r1, =1
    bl hello

.arm

.type hello, %function
hello:
    b reset_handler

дает

Disassembly of section .text:

00001000 <vector_table>:
    1000:   20001000    andcs   r1, r0, r0
    1004:   00001009    andeq   r1, r0, r9

00001008 <reset_handler>:
    1008:   4802        ldr r0, [pc, #8]    ; (1014 <hello+0x4>)
    100a:   4903        ldr r1, [pc, #12]   ; (1018 <hello+0x8>)
    100c:   f000 f80e   bl  102c <__hello_from_thumb>

00001010 <hello>:
    1010:   ea000002    b   1020 <__reset_handler_from_arm>
    1014:   00000000    andeq   r0, r0, r0
    1018:   00000001    andeq   r0, r0, r1
    101c:   00000000    andeq   r0, r0, r0

00001020 <__reset_handler_from_arm>:
    1020:   e59fc000    ldr r12, [pc]   ; 1028 <__reset_handler_from_arm+0x8>
    1024:   e12fff1c    bx  r12
    1028:   00001009    andeq   r1, r0, r9

0000102c <__hello_from_thumb>:
    102c:   4778        bx  pc
    102e:   e7fd        b.n 102c <__hello_from_thumb>
    1030:   eafffff6    b   1010 <hello>
    1034:   00000000    andeq   r0, r0, r0

в противном случае

.arm

hello:
    b reset_handler

дает не -функциональный код

Disassembly of section .text:

00001000 <vector_table>:
    1000:   20001000    andcs   r1, r0, r0
    1004:   00001009    andeq   r1, r0, r9

00001008 <reset_handler>:
    1008:   4802        ldr r0, [pc, #8]    ; (1014 <hello+0x4>)
    100a:   4903        ldr r1, [pc, #12]   ; (1018 <hello+0x8>)
    100c:   f000 f800   bl  1010 <hello>

00001010 <hello>:
    1010:   ea000002    b   1020 <__reset_handler_from_arm>
    1014:   00000000    andeq   r0, r0, r0
    1018:   00000001    andeq   r0, r0, r1
    101c:   00000000    andeq   r0, r0, r0

00001020 <__reset_handler_from_arm>:
    1020:   e59fc000    ldr r12, [pc]   ; 1028 <__reset_handler_from_arm+0x8>
    1024:   e12fff1c    bx  r12
    1028:   00001009    andeq   r1, r0, r9
    102c:   00000000    andeq   r0, r0, r0

теперь в cortex-m у вас нет режима охраны, поэтому нет взаимодействия, но для таблицы векторов и любых других функций на языке ассемблера, которые вы хотите вызвать из C или других высоких Уровень, вам нужно иметь объявление функции.

Объявление объекта, которое я никогда не видел, с тех пор использовал инструменты gnu с тех пор, как была добавлена ​​ветка, и выполнял голую металлическую загрузку чипа без необходимости в нем .. Так что не могу вам там помочь.

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

...