如何在C中重写这个asm代码?

时间:2014-02-01 12:55:07

标签: c 8051 iar disassembly

CPU:基于8051

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

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

以下是mov

  

MOV指令允许数据在任何内部之间传输   I-RAM空间或SFR位置以及累加器到内部之间   I-RAM空间或SFR位置。

和来自CPU数据表的movx指令描述

  

MOVX指令用于访问内部X-RAM和e-FLASH   区域。只能使用间接寻址。选择是否使用   一个字节的地址,@ Ri,其中Ri可以是R0或R1   选择寄存器组,或双字节地址,@ DPTR。

CPU datasheet

我在示例中看到的一些代码:

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

代码无法编译,因为它不知道xdata是什么,也在data上混淆了。所以我需要解释ecFlashaaa指向e-Flash的链接器......

2 个答案:

答案 0 :(得分:3)

Data和xdata可能是符合数据类型的编译器扩展或宏(在头文件中定义)。

用C编写代码非常简单。但是它是否生成了你想要的汇编程序将取决于编译器的智能程度。它是否了解系统中不同类型的内存?

您要做的是声明指向一个字节的指针,然后将指针的值(而不是它指向的内容)设置为您要访问的地址。然后你可以取消引用指针并将其设置为你想要的值。

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

这与示例中的内容非常相似,没有额外的数据/ xdata。

答案 1 :(得分:1)

示例代码之间的区别:

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

接受的答案是,使用xdata,编译器将生成与您的程序集snipet非常相似的代码。文字值0xaa将在一些指令中写入外部RAM中的位置0xaaa(或者,在您的情况下,外部RAM空间中的内存映射EEPROM)。

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

如果您使用实用程序功能(例如memcpy)并且确定内存类型一次然后使用优化的复制循环,则成本也不算太差。如果您编写自己的复制循环,如果不必要地使用通用指针,性能将会明显变差。

(我发现的示例代码可能是为Keil的C51编译器编写的)