如何用C语言重写这段汇编代码?

3

CPU:基于8051

以下代码将在外部闪存中的 0x0aaa 地址处设置值为 0xaa

mov     a,#0aah
mov     dptr,#X0aaa
movx    @dptr,a

以下是MOV和MOVX指令的CPU数据手册描述:
MOV指令允许在内部I-RAM空间或SFR位置之间以及累加器与内部I-RAM空间或SFR位置之间传输数据。
MOVX指令用于访问内部X-RAM和e-FLASH区域。只能使用间接寻址。可以选择使用一个字节地址@Ri,其中Ri可以是所选寄存器库中的R0或R1,或者使用两个字节地址@DPTR。
CPU数据手册请参考此链接:CPU datasheet 以下是一些示例代码:
xdata UCHAR * data ecFlashaaa  = (xdata UCHAR *)(0xaaa); 
*ecFlashaaa  = 0xaa;

代码无法编译,因为它不知道什么是xdata,同时也对data感到困惑。所以我需要以某种方式向链接器解释 ecFlashaaa 指向 e-Flash...


你是否拥有正确的编译器?你是否包含了适当的头文件? - Shahbaz
是的,我有。示例本身存在问题。我的项目中包含一个XCL文件,其中定义了段落。-D_XDATA_START=8000 // xdata内存的第一个地址。-D_XDATA_Z_START=_XDATA_START //芯片上XDATA内存的第一个地址。等等...但我不确定e-Flash是否在那里定义。即使已经定义,我如何将我的变量绑定到e-Flash。 - Pablo
我真的不了解微控制器,所以我不知道细节,但如果编译器不理解“xdata”(虽然该关键字存在于数据手册中!),我最好的猜测是要么是错误的编译器,要么是缺少头文件。 - Shahbaz
2个回答

3

数据和 xdata 可能是编译器扩展或宏(在头文件中定义),用于限定数据类型。

使用 C 语言编写代码非常简单。但是,它是否生成所需的汇编代码将取决于您的编译器有多聪明。它是否了解您系统中不同类型的内存?

您需要做的是声明一个指向字节的指针,然后将指针的值(而不是指向的值)设置为要访问的地址。然后,您可以对指针进行解引用并将其设置为所需的值。

unsigned char *flashptr = (unsigned char *)0xaaa;
*flashptr = 0xaa;

这基本上就是你在示例中所拥有的,没有额外的数据/扩展数据。


1

你的样例代码与以下代码不同:

xdata UCHAR * data ecFlashaaa  = (xdata UCHAR *)(0xaaa); 
*ecFlashaaa  = 0xaa;

被接受的答案是,使用xdata时编译器将生成非常类似于您的汇编片段的代码。 字面值0xaa将在几个指令中写入外部RAM中的位置0xaaa(或在您的情况下,似乎是内存映射的EEPROM在外部RAM空间中)。

有一个通用指针声明为unsigned char *flashptr的接受的答案,其中上字节将指示地址所在的存储空间。 因此,它不是指向xdata的指针,而是声明为通用指针,然后分配像{XDATA,0x0AAA}这样的值。 调用库例程来访问通用指针,使用正确的指令(movmovcmovx)来访问内存。

如果使用足够聪明以确定内存类型一次并使用优化的复制循环的实用程序函数(例如memcpy),成本不会太高。 如果您不必要地使用通用指针编写自己的复制循环,性能将显着下降。

你找到的我引用的示例代码可能是为Keil的C51编译器编写的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接