简体   繁体   English

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

[英]How to rewrite this asm code in C?

CPU: 8051 based CPU:基于8051

The following lines of code will set 0xaa value at 0x0aaa address in external flash memory. 以下代码行将0xaa值设置为外部闪存中的0x0aaa地址。

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

The following is mov 以下是mov

The MOV instruction allows data to be transferred between any internal I-RAM spaces or SFR locations and between accumulator to internal I-RAM spaces or SFR locations. MOV指令允许数据在任何内部I-RAM空间或SFR位置之间以及累加器与内部I-RAM空间或SFR位置之间传输。

and and movx instruction descriptions from CPU datasheet 和来自CPU数据表的movx指令说明

MOVX instruction is used to access the internal X-RAM and e-FLASH area. MOVX指令用于访问内部X-RAM和e-FLASH区域。 Only indirect addressing can be used. 只能使用间接寻址。 The choice whether to use a one-byte address, @Ri, where Ri can be either R0 or R1 of the selected register bank, or a two-byte address, @DPTR. 选择是使用单字节地址@Ri,其中Ri可以是所选寄存器组的R0或R1,也可以是双字节地址@DPTR。

CPU datasheet CPU数据表

Some code that I've seen in examples: 我在示例中看到的一些代码:

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

the code doesn't compile because it doesn't know what is xdata and also confused on data . 代码不能编译,因为它不知道什么是xdata ,也混淆了data So somehow I need to explain linker that ecFlashaaa is pointing to e-Flash... 所以我需要解释ecFlashaaa指向e-Flash的链接器......

Data and xdata are probably either compiler extensions or macros (defined in a header file) that qualify the data type. Data和xdata可能是编译器扩展或限定数据类型的宏(在头文件中定义)。

Writing the code in C is pretty simple. 用C编写代码非常简单。 But whether or not it generates the assembler you want is going to depend on how smart your compiler is. 但是它是否生成了你想要的汇编程序将取决于编译器的智能程度。 Does it know about the different kinds of memory in your system? 它是否了解系统中不同类型的内存?

What you want to do is declare a pointer to a byte, and then set the value of the pointer (not what it points to) to the address you wish to access. 你想要做的是声明一个指向一个字节的指针,然后将指针的值(而不是它指向的)设置为你想要访问的地址。 Then you can dereference the pointer and set it to the value you want. 然后,您可以取消引用指针并将其设置为您想要的值。

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

Which is pretty much what you have in the example, without the extra data/xdata in there. 这与示例中的内容非常相似,没有额外的data / xdata。

The difference between your sample code: 您的示例代码之间的区别:

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

And the accepted answer is that with xdata the compiler will generate code very similar to your assembly snipet. 接受的答案是,使用xdata ,编译器将生成与您的程序集snipet非常相似的代码。 The literal value 0xaa will be written to location 0xaaa in external RAM (or, in your case, what appears to be a memory mapped EEPROM in the external RAM space) in a few instructions. 文字值0xaa将被写入外部RAM中的位置0xaaa (或者,在您的情况下,在外部RAM空间中看起来0xaaa存储器映射的EEPROM)在一些指令中。

The accepted answer with a generic pointer declared unsigned char *flashptr will use a 3-byte type for flashptr where the upper byte will indicate which memory space the address is in. So instead of being declared as a pointer to xdata it is declared as a generic pointer and then assigned a value like {XDATA, 0x0AAA} . 使用通用指针声明unsigned char *flashptr的接受答案将使用3字节类型的flashptr ,其中高位字节将指示地址所在的内存空间。因此,不是声明为指向xdata的指针而是声明为通用指针,然后分配一个像{XDATA, 0x0AAA} Access to generic pointers is by calling a library routine which uses the correct instruction ( mov , movc , or movx ) to access the memory. 访问通用指针是通过调用库例程,该例程使用正确的指令( movmovcmovx )来访问内存。

The cost isn't too bad if you use a utility function (eg memcpy ) which is smart enough to determine the memory type once and then use an optimized copy loop. 如果你使用了效用函数(例如,成本是不是太糟糕memcpy ),这是足够聪明的,一旦确定内存类型,然后使用经过优化的复制循环。 If you write your own copy loop the performance will be significantly worse if you use a generic pointer unnecessarily. 如果您编写自己的复制循环,如果不必要地使用通用指针,性能将会明显变差。

(The sample code you found that I quoted was probably written for Keil's C51 compiler) (我发现的示例代码可能是为Keil的C51编译器编写的)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM