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
当我删除 .type x
宏时,我没有通过调试器看到寄存器有任何变化,但是根据 this Whosebug post .type
-macro 应该没有效果.
为什么当我删除 .type
-macros 时寄存器 r0
和 r1
保持不变?
.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 工具,并且一直在裸机引导芯片的东西而不需要它...所以不能在这方面帮助你。
它们保持不变的原因是因为你挂了芯片或者强制它进入了一个你没有定义的处理程序所以又挂了芯片。处理器状态应该已经改变以指示您所处的故障模式。
我正在学习一些用于 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
当我删除 .type x
宏时,我没有通过调试器看到寄存器有任何变化,但是根据 this Whosebug post .type
-macro 应该没有效果.
为什么当我删除 .type
-macros 时寄存器 r0
和 r1
保持不变?
.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 工具,并且一直在裸机引导芯片的东西而不需要它...所以不能在这方面帮助你。
它们保持不变的原因是因为你挂了芯片或者强制它进入了一个你没有定义的处理程序所以又挂了芯片。处理器状态应该已经改变以指示您所处的故障模式。