我正在为 NXP LPC810 微控制器编写嵌入式 C/汇编代码(只是一个爱好项目)。
我有一个功能fn
。我还有一个该函数机器代码的精确副本,位于uint8_t
. (我已经检查了十六进制文件。)
我创建了一个函数指针fnptr
,其类型与fn
并使用强制转换将其指向数组。
这一切都在没有警告的情况下交叉编译。
当 MCU 执行fn
时,它工作正常。
当 MCU 执行fnptr
时它崩溃(我看不到任何调试,因为只有 8 个引脚,全部在使用中)。
代码与位置无关。
该数组具有正确的 4 字节对齐方式。
fn
在.text
elf文件的部分。
该数组被强制进入.text
elf 文件的部分(仍在闪存中,而不是 RAM)。
我假设在这样一个基本的 Coretex M0+ MCU 上没有类似 NX 的功能。(Cortex M3 和 M4 确实具有某种形式的代码只读存储器保护。)
数组中的机器码不起作用还有其他原因吗?
更新:
这是代码:
#include "stdio.h"
#include "serial.h"
extern "C" void SysTick_Handler() {
// generate an interrupt for delay
}
void delay(int millis) {
while (--millis >= 0) {
__WFI(); // wait for SysTick interrupt
}
}
extern "C" int fn(int a, int b) {
return a + b;
}
/* arm-none-eabi-objdump -d firmware.elf
00000162 <fn>:
162: 1840 adds r0, r0, r1
164: 4770 bx lr
166: 46c0 nop ; (mov r8, r8)
*/
extern "C" const uint8_t machine_code[6] __attribute__((aligned (4))) __attribute__((section (".text"))) = {
0x40,0x18,
0x70,0x47,
0xc0,0x46
};
int main() {
LPC_SWM->PINASSIGN0 = 0xFFFFFF04UL;
serial.init(LPC_USART0, 115200);
SysTick_Config(12000000/1000); // 1ms ticks
int(*fnptr)(int a, int b) = (int(*)(int, int))machine_code;
for (int a = 0; ; a++) {
int c = fnptr(a, 1000000);
printf("Hello world2 %d.\n", c);
delay(1000);
}
}
这是反汇编的输出arm-none-eabi-objdump -D -Mforce-thumb firmware.elf
:
00000162 <fn>:
162: 1840 adds r0, r0, r1
164: 4770 bx lr
166: 46c0 nop ; (mov r8, r8)
00000168 <machine_code>:
168: 1840 adds r0, r0, r1
16a: 4770 bx lr
16c: 46c0 nop ; (mov r8, r8)
16e: 46c0 nop ; (mov r8, r8)
00000170 <main>:
...