构建最少的汇编代码会产生空的二进制文件
building minimal piece of assembly code produces empty binary file
我正在尝试为我的 MCU(tms570lc4357zwt、ARM Cortex-R5f)构建一个最小的启动代码,但是当我构建它并将其转换为二进制格式时,生成的大小 。 bin 文件为 0.
测试文件的结构是:
test
+--CMakeLists.txt
+--gnu.cmake
+--isr.S
+--linker.ld
我使用的工具版本是:
- arm-none-eabi-gcc: 8-2018-q4-major
- cmake: 3.15.2
这是我的最小汇编代码 (isr.S):
.arm
.global isr_vector
.global bootloader
.section .flash_code_isr_vector
isr_vector:
LDR pc, = bootloader /* reset. */
LDR pc, = 0x08000004 /* undefined instruction. */
LDR pc, = 0x08000008 /* system call. */
LDR pc, = 0x0800000C /* prefetch abort. */
LDR pc, = 0x08000010 /* data abort. */
LDR pc, = 0x08000014 /* reserved. */
LDR pc, = 0x08000018 /* IRQ. */
LDR pc, = 0x0800001C /* FIQ. */
.section .flash_code_bootloader
bootloader:
B .
我使用以下链接描述文件 (linker.ld):
MEMORY
{
FLASH_TCM (rx) : ORIGIN = 0x00000000, LENGTH = 4M
RAM_TCM (rwx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM_ECC (rwx) : ORIGIN = 0x08400000, LENGTH = 512K
}
ENTRY(isr_vector)
SECTIONS
{
.flash_code_isr_vector 0x00000000 :
{
KEEP(*(.flash_code_isr_vector))
} > FLASH_TCM
.flash_code_bootloader 0x00000100 :
{
*(.flash_code_bootloader)
} > FLASH_TCM
}
下面是我用来构建它的工具链文件 (gnu.cmake) 和 cmake 文件 (CMakeLists.txt):
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
find_program(ASM_COMPILER arm-none-eabi-gcc)
find_program(C_COMPILER arm-none-eabi-gcc)
find_program(LINKER arm-none-eabi-gcc)
find_program(ARCHIVER arm-none-eabi-ar)
find_program(RANLIB arm-none-eabi-ranlib)
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
set(CMAKE_C_COMPILER ${C_COMPILER})
set(CMAKE_C_LINK_EXECUTABLE ${LINKER})
set(CMAKE_AR ${ARCHIVER})
set(CMAKE_RANLIB ${RANLIB})
add_compile_options(-mbig-endian
-march=armv7-r
-Wall
-Wextra)
add_link_options(-mbig-endian
-nostdlib
-Wall
-Wextra)
cmake_minimum_required(VERSION 3.0)
project(test VERSION 0.0.1 LANGUAGES ASM)
add_executable(isr.elf isr.S)
add_compile_options(isr.elf PRIVATE -O0 -g)
set_target_properties(isr.elf PROPERTIES
LINK_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld")
add_custom_target(isr.bin
DEPENDS isr.elf
COMMAND arm-none-eabi-objcopy -O binary isr.elf isr.bin
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_custom_target(isr.asm
DEPENDS isr.elf
COMMAND arm-none-eabi-objdump -D isr.elf > isr.asm
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_custom_target(isr.size
DEPENDS isr.elf
COMMAND arm-none-eabi-size isr.elf -A -t -x
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
问题可以通过 运行 重现(在包含所有文件的文件夹中)mkdir build && cd build && cmake .. -DCMAKE_TOOLCHAIN_FILE=../gnu.cmake
问题来了:
当我询问 .elf 的大小时(调用 isr.size
目标),我得到
isr.elf :
section size addr
.flash_code_isr_vector 0x40 0x0
.flash_code_bootloader 0x4 0x100
.ARM.attributes 0x1d 0x0
Total 0x61
这似乎是合理的。现在当我生成 .bin 文件(调用 isr.bin
目标)时,生成的文件大小为 0。有人知道为什么吗?因为当我反汇编 .elf 文件(调用 isr.asm
目标)时,生成的汇编代码似乎是正确的:
isr.elf: file format elf32-bigarm
Disassembly of section .flash_code_isr_vector:
00000000 <isr_vector>:
0: e59ff018 ldr pc, [pc, #24] ; 20 <isr_vector+0x20>
4: e59ff018 ldr pc, [pc, #24] ; 24 <isr_vector+0x24>
8: e59ff018 ldr pc, [pc, #24] ; 28 <isr_vector+0x28>
c: e59ff018 ldr pc, [pc, #24] ; 2c <isr_vector+0x2c>
10: e59ff018 ldr pc, [pc, #24] ; 30 <isr_vector+0x30>
14: e59ff018 ldr pc, [pc, #24] ; 34 <isr_vector+0x34>
18: e59ff018 ldr pc, [pc, #24] ; 38 <isr_vector+0x38>
1c: e59ff018 ldr pc, [pc, #24] ; 3c <isr_vector+0x3c>
20: 00000100 andeq r0, r0, r0, lsl #2
24: 08000004 stmdaeq r0, {r2}
28: 08000008 stmdaeq r0, {r3}
2c: 0800000c stmdaeq r0, {r2, r3}
30: 08000010 stmdaeq r0, {r4}
34: 08000014 stmdaeq r0, {r2, r4}
38: 08000018 stmdaeq r0, {r3, r4}
3c: 0800001c stmdaeq r0, {r2, r3, r4}
Disassembly of section .flash_code_bootloader:
00000100 <bootloader>:
100: eafffffe b 100 <bootloader>
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 41000000 mrsmi r0, (UNDEF: 0)
4: 1c616561 cfstr64ne mvdx6, [r1], #-388 ; 0xfffffe7c
8: 62690001 rsbvs r0, r9, #1, 0
c: 00000012 andeq r0, r0, r2, lsl r0
10: 05372d52 ldreq r2, [r7, #-3410]! ; 0xfffff2ae
14: 00060a07 andeq r0, r6, r7, lsl #20
18: 52080109 andpl r0, r8, #1073741826 ; 0x40000002
1c: Address 0x000000000000001c is out of bounds.
提前致谢。
在您的汇编代码中,您没有将您的部分标记为可分配,因此当您生成二进制文件时它们不会被输出。如果您使用
转储了 header 文件
arm-none-eabi-objdump -x isr.elf
输出看起来类似于:
isr.elf: file format elf32-bigarm
isr.elf
architecture: arm, flags 0x00000012:
EXEC_P, HAS_SYMS
start address 0x00000000
private flags = 5000200: [Version5 EABI] [soft-float ABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .flash_code_isr_vector 00000040 00000000 00000000 00000034 2**2
CONTENTS, READONLY
1 .flash_code_bootloadery 00000004 00000000 00000000 00000074 2**2
CONTENTS, READONLY
2 .ARM.attributes 0000001d 00000000 00000000 00000078 2**0
CONTENTS, READONLY
标志只有CONTENTS
和READONLY
。它缺少 ALLOC
(可分配)标志。由于您的部分似乎也是代码,因此我会考虑通过添加 "ax"
属性来修改 isr.S
,例如:
.arm
.global isr_vector
.global bootloader
.section .flash_code_isr_vector,"ax",%progbits
isr_vector:
LDR pc, = bootloader /* reset. */
LDR pc, = 0x08000004 /* undefined instruction. */
LDR pc, = 0x08000008 /* system call. */
LDR pc, = 0x0800000C /* prefetch abort. */
LDR pc, = 0x08000010 /* data abort. */
LDR pc, = 0x08000014 /* reserved. */
LDR pc, = 0x08000018 /* IRQ. */
LDR pc, = 0x0800001C /* FIQ. */
.section .flash_code_bootloader,"ax",%progbits
bootloader:
B .
如果您重建代码,bin
文件应该是 non-zero 并且 ELF headers 现在应该看起来像:
Sections:
Idx Name Size VMA LMA File off Algn
0 .flash_code_isr_vector 00000040 00000000 00000000 00010000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .flash_code_bootloader 00000004 00000100 00000100 00010100 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .ARM.attributes 0000001d 00000000 00000000 00010104 2**0
CONTENTS, READONLY
.section
指令是 documented for ELF 为:
ELF Version
This is one of the ELF section stack manipulation
directives. The others are .subsection (see SubSection), .pushsection
(see PushSection), .popsection (see PopSection), and .previous (see
Previous).
For ELF targets, the .section directive is used like this:
.section name [, "flags"[, @type[,flag_specific_arguments]]]
[snip]
a section is allocatable
d section is a GNU_MBIND section
e section is excluded from executable and shared library.
w section is writable
x section is executable
M section is mergeable
S section contains zero terminated strings
G section is a member of a section group
T section is used for thread-local-storage
? section is a member of the previously-current section’s group, if
any
[snip]
The optional type argument may contain one of the following constants:
@progbits section contains data
@nobits section does not contain data (i.e., section only occupies
space)
[snip]
Note on targets where the @ character is the start of a comment (eg
ARM) then another character is used instead. For example the ARM port
uses the % character.
我正在尝试为我的 MCU(tms570lc4357zwt、ARM Cortex-R5f)构建一个最小的启动代码,但是当我构建它并将其转换为二进制格式时,生成的大小 。 bin 文件为 0.
测试文件的结构是:
test
+--CMakeLists.txt
+--gnu.cmake
+--isr.S
+--linker.ld
我使用的工具版本是:
- arm-none-eabi-gcc: 8-2018-q4-major
- cmake: 3.15.2
这是我的最小汇编代码 (isr.S):
.arm
.global isr_vector
.global bootloader
.section .flash_code_isr_vector
isr_vector:
LDR pc, = bootloader /* reset. */
LDR pc, = 0x08000004 /* undefined instruction. */
LDR pc, = 0x08000008 /* system call. */
LDR pc, = 0x0800000C /* prefetch abort. */
LDR pc, = 0x08000010 /* data abort. */
LDR pc, = 0x08000014 /* reserved. */
LDR pc, = 0x08000018 /* IRQ. */
LDR pc, = 0x0800001C /* FIQ. */
.section .flash_code_bootloader
bootloader:
B .
我使用以下链接描述文件 (linker.ld):
MEMORY
{
FLASH_TCM (rx) : ORIGIN = 0x00000000, LENGTH = 4M
RAM_TCM (rwx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM_ECC (rwx) : ORIGIN = 0x08400000, LENGTH = 512K
}
ENTRY(isr_vector)
SECTIONS
{
.flash_code_isr_vector 0x00000000 :
{
KEEP(*(.flash_code_isr_vector))
} > FLASH_TCM
.flash_code_bootloader 0x00000100 :
{
*(.flash_code_bootloader)
} > FLASH_TCM
}
下面是我用来构建它的工具链文件 (gnu.cmake) 和 cmake 文件 (CMakeLists.txt):
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
find_program(ASM_COMPILER arm-none-eabi-gcc)
find_program(C_COMPILER arm-none-eabi-gcc)
find_program(LINKER arm-none-eabi-gcc)
find_program(ARCHIVER arm-none-eabi-ar)
find_program(RANLIB arm-none-eabi-ranlib)
set(CMAKE_ASM_COMPILER ${ASM_COMPILER})
set(CMAKE_C_COMPILER ${C_COMPILER})
set(CMAKE_C_LINK_EXECUTABLE ${LINKER})
set(CMAKE_AR ${ARCHIVER})
set(CMAKE_RANLIB ${RANLIB})
add_compile_options(-mbig-endian
-march=armv7-r
-Wall
-Wextra)
add_link_options(-mbig-endian
-nostdlib
-Wall
-Wextra)
cmake_minimum_required(VERSION 3.0)
project(test VERSION 0.0.1 LANGUAGES ASM)
add_executable(isr.elf isr.S)
add_compile_options(isr.elf PRIVATE -O0 -g)
set_target_properties(isr.elf PROPERTIES
LINK_FLAGS "-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld")
add_custom_target(isr.bin
DEPENDS isr.elf
COMMAND arm-none-eabi-objcopy -O binary isr.elf isr.bin
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_custom_target(isr.asm
DEPENDS isr.elf
COMMAND arm-none-eabi-objdump -D isr.elf > isr.asm
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
add_custom_target(isr.size
DEPENDS isr.elf
COMMAND arm-none-eabi-size isr.elf -A -t -x
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
问题可以通过 运行 重现(在包含所有文件的文件夹中)mkdir build && cd build && cmake .. -DCMAKE_TOOLCHAIN_FILE=../gnu.cmake
问题来了:
当我询问 .elf 的大小时(调用 isr.size
目标),我得到
isr.elf :
section size addr
.flash_code_isr_vector 0x40 0x0
.flash_code_bootloader 0x4 0x100
.ARM.attributes 0x1d 0x0
Total 0x61
这似乎是合理的。现在当我生成 .bin 文件(调用 isr.bin
目标)时,生成的文件大小为 0。有人知道为什么吗?因为当我反汇编 .elf 文件(调用 isr.asm
目标)时,生成的汇编代码似乎是正确的:
isr.elf: file format elf32-bigarm
Disassembly of section .flash_code_isr_vector:
00000000 <isr_vector>:
0: e59ff018 ldr pc, [pc, #24] ; 20 <isr_vector+0x20>
4: e59ff018 ldr pc, [pc, #24] ; 24 <isr_vector+0x24>
8: e59ff018 ldr pc, [pc, #24] ; 28 <isr_vector+0x28>
c: e59ff018 ldr pc, [pc, #24] ; 2c <isr_vector+0x2c>
10: e59ff018 ldr pc, [pc, #24] ; 30 <isr_vector+0x30>
14: e59ff018 ldr pc, [pc, #24] ; 34 <isr_vector+0x34>
18: e59ff018 ldr pc, [pc, #24] ; 38 <isr_vector+0x38>
1c: e59ff018 ldr pc, [pc, #24] ; 3c <isr_vector+0x3c>
20: 00000100 andeq r0, r0, r0, lsl #2
24: 08000004 stmdaeq r0, {r2}
28: 08000008 stmdaeq r0, {r3}
2c: 0800000c stmdaeq r0, {r2, r3}
30: 08000010 stmdaeq r0, {r4}
34: 08000014 stmdaeq r0, {r2, r4}
38: 08000018 stmdaeq r0, {r3, r4}
3c: 0800001c stmdaeq r0, {r2, r3, r4}
Disassembly of section .flash_code_bootloader:
00000100 <bootloader>:
100: eafffffe b 100 <bootloader>
Disassembly of section .ARM.attributes:
00000000 <.ARM.attributes>:
0: 41000000 mrsmi r0, (UNDEF: 0)
4: 1c616561 cfstr64ne mvdx6, [r1], #-388 ; 0xfffffe7c
8: 62690001 rsbvs r0, r9, #1, 0
c: 00000012 andeq r0, r0, r2, lsl r0
10: 05372d52 ldreq r2, [r7, #-3410]! ; 0xfffff2ae
14: 00060a07 andeq r0, r6, r7, lsl #20
18: 52080109 andpl r0, r8, #1073741826 ; 0x40000002
1c: Address 0x000000000000001c is out of bounds.
提前致谢。
在您的汇编代码中,您没有将您的部分标记为可分配,因此当您生成二进制文件时它们不会被输出。如果您使用
转储了 header 文件arm-none-eabi-objdump -x isr.elf
输出看起来类似于:
isr.elf: file format elf32-bigarm isr.elf architecture: arm, flags 0x00000012: EXEC_P, HAS_SYMS start address 0x00000000 private flags = 5000200: [Version5 EABI] [soft-float ABI] Sections: Idx Name Size VMA LMA File off Algn 0 .flash_code_isr_vector 00000040 00000000 00000000 00000034 2**2 CONTENTS, READONLY 1 .flash_code_bootloadery 00000004 00000000 00000000 00000074 2**2 CONTENTS, READONLY 2 .ARM.attributes 0000001d 00000000 00000000 00000078 2**0 CONTENTS, READONLY
标志只有CONTENTS
和READONLY
。它缺少 ALLOC
(可分配)标志。由于您的部分似乎也是代码,因此我会考虑通过添加 "ax"
属性来修改 isr.S
,例如:
.arm
.global isr_vector
.global bootloader
.section .flash_code_isr_vector,"ax",%progbits
isr_vector:
LDR pc, = bootloader /* reset. */
LDR pc, = 0x08000004 /* undefined instruction. */
LDR pc, = 0x08000008 /* system call. */
LDR pc, = 0x0800000C /* prefetch abort. */
LDR pc, = 0x08000010 /* data abort. */
LDR pc, = 0x08000014 /* reserved. */
LDR pc, = 0x08000018 /* IRQ. */
LDR pc, = 0x0800001C /* FIQ. */
.section .flash_code_bootloader,"ax",%progbits
bootloader:
B .
如果您重建代码,bin
文件应该是 non-zero 并且 ELF headers 现在应该看起来像:
Sections: Idx Name Size VMA LMA File off Algn 0 .flash_code_isr_vector 00000040 00000000 00000000 00010000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .flash_code_bootloader 00000004 00000100 00000100 00010100 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .ARM.attributes 0000001d 00000000 00000000 00010104 2**0 CONTENTS, READONLY
.section
指令是 documented for ELF 为:
ELF Version
This is one of the ELF section stack manipulation directives. The others are .subsection (see SubSection), .pushsection (see PushSection), .popsection (see PopSection), and .previous (see Previous).
For ELF targets, the .section directive is used like this:
.section name [, "flags"[, @type[,flag_specific_arguments]]]
[snip]
a section is allocatable
d section is a GNU_MBIND section
e section is excluded from executable and shared library.
w section is writable
x section is executable
M section is mergeable
S section contains zero terminated strings
G section is a member of a section group
T section is used for thread-local-storage
? section is a member of the previously-current section’s group, if any
[snip]
The optional type argument may contain one of the following constants:
@progbits section contains data
@nobits section does not contain data (i.e., section only occupies space)
[snip]
Note on targets where the @ character is the start of a comment (eg ARM) then another character is used instead. For example the ARM port uses the % character.