这段代码:
似乎它正在加载到 .rodata 的顶部位置一个指针(
注意:当我删除
问题的背景是,我正在尝试手动优化一些 C 固件,并注意到这个看起来多余的
注意:所有这些都是针对 ARM Thumb 指令集编译的,如下所示(使用 arm-none-eabi-gcc 版本 11.2.1):
注意:这里的示例代码旨在表示一个更大代码库的片段。如果
const char padding[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
const char myTable[] = { 1, 2, 3, 4 };
int keepPadding() {
return (int)(&padding);
}
int foo() {
return (int)(&myTable); // <-- this is the part I'm looking at
}
以下是针对thumb指令集的汇编代码(为了清晰起见进行了缩写),请特别注意foo
函数中第二条指令的adds
操作:
...
foo:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
ldr r0, .L5
@ sp needed
adds r0, r0, #10
bx lr
.L6:
.align 2
.L5:
.word .LANCHOR0
.size foo, .-foo
.align 1
.global bar
.syntax unified
.code 16
.thumb_func
.type bar, %function
...
myTable:
.ascii "\001\002\003\004"
似乎它正在加载到 .rodata 的顶部位置一个指针(
ldr
),然后通过编程方式偏移至 myTable
的位置(adds
)。但是为什么不直接加载表格本身的地址呢?注意:当我删除
const
时,它似乎会在没有 ADDS
指令的情况下执行(使用 .data
中的 myTable
)。问题的背景是,我正在尝试手动优化一些 C 固件,并注意到这个看起来多余的
adds
指令,所以我想知道是否有一种重构我的代码的方法来摆脱它。注意:所有这些都是针对 ARM Thumb 指令集编译的,如下所示(使用 arm-none-eabi-gcc 版本 11.2.1):
arm-none-eabi-gcc -Os -c -mcpu=cortex-m0 -mthumb temp.c -S
注意:这里的示例代码旨在表示一个更大代码库的片段。如果
myTable
是唯一编译的内容,则它会落在.rodata
的偏移量0处,并且adds
指令将消失,但这并不是真实场景的典型情况。为了表示产生这种汇编语言的典型真实世界情况,我在表格前添加了填充物。
另请参见这里在Godbolt上的重现
ldr
。 - Jesterldr
指令的数量。但我不确定。 - fuz