我试图在用于ARM的GNU GCC C编译器中声明指向字符串的16位指针,以减少闪存消耗。我有两种语言的大约200个字符串,因此减少指针的大小可以节省800个字节的Flash。
起初,我试图在C语言中将32位指针声明为“ unsigned int”,这没关系:
const unsigned char str1[] ="Hello word";
const unsigned int ptr1 = &str1;
然后我尝试将指针减少到16位:
const unsigned short ptr1 = &str1;
我收到错误消息:“错误:初始化器元素在加载时无法计算”
然后我尝试:
const unsigned short ptr1 = (&str1 & 0xFFFF);
我得到:“错误:二进制&(具有'const unsigned char(*)[11]'和'int')的无效操作数”]
经过多次尝试,我最终进入了汇编:
.section .rodata.strings
.align 2
ptr0:
ptr3: .short (str3-str0)
ptr4: .short (str4-str0)
str0:
str3: .asciz "3-th string"
str4: .asciz "4-th string"
编译通过得很好,但是现在我在尝试从C代码引用指针:ptr4和ptr0时遇到问题。试图将“ ptr4-ptr0”作为8位参数传递给C函数:
getStringFromTable (ptr4-ptr0)
声明为:
void getStringFromTable (unsigned char stringIndex)
我输入了错误的代码,例如:
ldr r3, [pc, #28] ; (0x8000a78 <main+164>)
ldrb r1, [r3, #0]
ldr r3, [pc, #28] ; (0x8000a7c <main+168>)
ldrb r3, [r3, #0]
subs r1, r1, r3
uxtb r1, r1
bl 0x8000692 <getStringFromTable>
而不是像这样的东西:
movs r0, #2
bl 0x8000692 <getStringFromTable>
我将不胜感激任何建议。
我使用32位STM32 Cortex-M0处理器。实际上,我需要一个指向200个字符串的短指针数组(我在下面的示例中仅显示2个字符串):
const unsigned char str1[] ="First string";
const unsigned char str2[] ="Second string";
const unsigned short ptrs[] = {&str1, &str2}; //this line generate error
并且为了保存闪存,ptrs []数组中的每个元素应为16位,而不是默认的32位。
如果您认为您的编译器是基于16位的,则可以这样做。
const unsigned char str1 [] =“你好单词”;int temp_addr = str1;
这里str1是指针本身,因此您不需要使用&运算符。如果编译器基于16位,则存储在str1中的指针值如下所示0x0000aabb
您可以使用移位运算符<<
unsigned short sh_address = temp_addr << 16; // 0xaabb将获得。
希望这对您有帮助