ARM 程序集在没有 .type 宏的情况下无法工作

ARM assembly not working without .type macro

我正在学习一些用于 STM32F0 (ARM Cortex M0) 微控制器的 (ARMv6-M) 汇编器。对于初学者,我编写了一个脚本,其中我将寄存器 r0 初始化为 0 并将 r1 初始化为 1,最后,r0 递增 1在一个循环中。使用调试器,即 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

并基于 this excellent tutorial.

当我删除 .type x 宏时,我没有通过调试器看到寄存器有任何变化,但是根据 this Whosebug post .type-macro 应该没有效果.

为什么当我删除 .type-macros 时寄存器 r0r1 保持不变?

.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

用于重置的向量 table 具有与 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_func 并且找到的下一个标签被认为是一个函数:

.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 链接器)为您在函数之间蹦床,这也是 thumb 交互工作所必需的:

.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 上你没有 arm 模式所以没有互通,但是对于向量 table 和任何其他你想从 C 或其他高级语言调用的汇编语言函数你需要有函数声明。

我从未见过的对象声明,自从添加 arm 以来一直在使用 gnu 工具,并且一直在裸机引导芯片的东西而不需要它...所以不能在这方面帮助你。

它们保持不变的原因是因为你挂了芯片或者强制它进入了一个你没有定义的处理程序所以又挂了芯片。处理器状态应该已经改变以指示您所处的故障模式。