如何用“.word”解释汇编启动代码
How to interpret the assembly boot code with ".word"
我正在一步一步慢慢研究汇编中的启动代码。
我找到了下面的程序集启动代码。但我仍然无法完全理解。
到目前为止,据我了解,
首先,第1行执行后,
然后转到第 2 行,
然后转到第 5 行,
然后到第6行,加载0x40002001到r1寄存器,
然后转到第7行,跳转到r1的寄存器地址(PC更新为0x40002001)
到这里我明白了。
但是我无法理解第3行和第4行的目的和含义。
你能告诉我第 3 行和第 4 行有什么意义和目的吗?
1 .section .text
2 .globl main
3 .word 0x40002000
4 .word main+1
5 main:
6 ldr r1, st0
7 bx r1
8 .align 4
9 st0:
10 .word 0x40002001
您需要阅读 cortex-m3 的文档。这是来自 ARM 的网站,不一定是芯片供应商。
简短的回答是.words 在那里描述向量 table,这些不是指令。参数含义可能不同的 .align 是为了确保常量正确对齐以避免数据中止。
地址 0x00000000 处的第一个 item/word 是在复位时加载到堆栈指针中的值。第二个词是重置向量。作为拇指指令集机器,它希望在向量 table.
中设置 lsbit 的地址
然后代码分支到 0x40002000,lsbit 被剥离,但是 bx 工作所必需的。 (PC 得到 0x40002000 而不是 0x40002001)
你没有指定汇编语言 (assembler),如果这要使用 gnu 汇编器那么你可以清理一下:
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
ldr r1, st0
bx r1
.align
st0:
.word 0x40002001
制作中
Disassembly of section .text:
00000000 <_start>:
0: 40002000 andmi r2, r0, r0
4: 00000009 andeq r0, r0, r9
00000008 <main>:
8: 4900 ldr r1, [pc, #0] ; (c <st0>)
a: 4708 bx r1
0000000c <st0>:
c: 40002001 andmi r2, r0, r1
现在的问题是你如何在重置前将程序放入内存中的 0x40002000?
你可以在 gnu 汇编程序中使用这个技巧来解决 .align 混淆或可能的浪费(在 .align 之后使用错误的值)
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
ldr r1, =0x40002001
bx r1
Disassembly of section .text:
00000000 <_start>:
0: 40002000 andmi r2, r0, r0
4: 00000009 andeq r0, r0, r9
00000008 <main>:
8: 4900 ldr r1, [pc, #0] ; (c <main+0x4>)
a: 4708 bx r1
c: 40002001 andmi r2, r0, r1
对齐是为了避免这样的事情导致错误:
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
nop
ldr r1, st0
bx r1
.align
st0: .word 0x40002001
.align 导致在不需要的地方添加填充,因为值落在对齐的位置。
Disassembly of section .text:
00000000 <_start>:
0: 40002000 andmi r2, r0, r0
4: 00000009 andeq r0, r0, r9
00000008 <main>:
8: 46c0 nop ; (mov r8, r8)
a: 4901 ldr r1, [pc, #4] ; (10 <st0>)
c: 4708 bx r1
e: bf00 nop
00000010 <st0>:
10: 40002001 andmi r2, r0, r1
这也为你对齐,在这种情况下用零填充,没有使用对齐,让它把数据放在一个池中
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
nop
ldr r1, =0x40002001
bx r1
它没有很好地反汇编,因此 intel hex 输出形式显示了发生的情况。
:100000000020004009000000C046014908470000E8
:04001000012000408B
:00000001FF
同上但填充为0x0000
0x4708 (bx r1)
0x0000
0x40002001
我正在一步一步慢慢研究汇编中的启动代码。
我找到了下面的程序集启动代码。但我仍然无法完全理解。
到目前为止,据我了解,
首先,第1行执行后,
然后转到第 2 行,
然后转到第 5 行,
然后到第6行,加载0x40002001到r1寄存器,
然后转到第7行,跳转到r1的寄存器地址(PC更新为0x40002001)
到这里我明白了。
但是我无法理解第3行和第4行的目的和含义。
你能告诉我第 3 行和第 4 行有什么意义和目的吗?
1 .section .text
2 .globl main
3 .word 0x40002000
4 .word main+1
5 main:
6 ldr r1, st0
7 bx r1
8 .align 4
9 st0:
10 .word 0x40002001
您需要阅读 cortex-m3 的文档。这是来自 ARM 的网站,不一定是芯片供应商。
简短的回答是.words 在那里描述向量 table,这些不是指令。参数含义可能不同的 .align 是为了确保常量正确对齐以避免数据中止。
地址 0x00000000 处的第一个 item/word 是在复位时加载到堆栈指针中的值。第二个词是重置向量。作为拇指指令集机器,它希望在向量 table.
中设置 lsbit 的地址然后代码分支到 0x40002000,lsbit 被剥离,但是 bx 工作所必需的。 (PC 得到 0x40002000 而不是 0x40002001)
你没有指定汇编语言 (assembler),如果这要使用 gnu 汇编器那么你可以清理一下:
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
ldr r1, st0
bx r1
.align
st0:
.word 0x40002001
制作中
Disassembly of section .text:
00000000 <_start>:
0: 40002000 andmi r2, r0, r0
4: 00000009 andeq r0, r0, r9
00000008 <main>:
8: 4900 ldr r1, [pc, #0] ; (c <st0>)
a: 4708 bx r1
0000000c <st0>:
c: 40002001 andmi r2, r0, r1
现在的问题是你如何在重置前将程序放入内存中的 0x40002000?
你可以在 gnu 汇编程序中使用这个技巧来解决 .align 混淆或可能的浪费(在 .align 之后使用错误的值)
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
ldr r1, =0x40002001
bx r1
Disassembly of section .text:
00000000 <_start>:
0: 40002000 andmi r2, r0, r0
4: 00000009 andeq r0, r0, r9
00000008 <main>:
8: 4900 ldr r1, [pc, #0] ; (c <main+0x4>)
a: 4708 bx r1
c: 40002001 andmi r2, r0, r1
对齐是为了避免这样的事情导致错误:
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
nop
ldr r1, st0
bx r1
.align
st0: .word 0x40002001
.align 导致在不需要的地方添加填充,因为值落在对齐的位置。
Disassembly of section .text:
00000000 <_start>:
0: 40002000 andmi r2, r0, r0
4: 00000009 andeq r0, r0, r9
00000008 <main>:
8: 46c0 nop ; (mov r8, r8)
a: 4901 ldr r1, [pc, #4] ; (10 <st0>)
c: 4708 bx r1
e: bf00 nop
00000010 <st0>:
10: 40002001 andmi r2, r0, r1
这也为你对齐,在这种情况下用零填充,没有使用对齐,让它把数据放在一个池中
.cpu cortex-m3
.thumb
.globl _start
_start:
.word 0x40002000
.word main
.thumb_func
main:
nop
ldr r1, =0x40002001
bx r1
它没有很好地反汇编,因此 intel hex 输出形式显示了发生的情况。
:100000000020004009000000C046014908470000E8
:04001000012000408B
:00000001FF
同上但填充为0x0000
0x4708 (bx r1)
0x0000
0x40002001