We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi All, I'm more of a Assembly guy than C. I came across this forum when I am seeking for some quick guide of sharing data registers / variables of different files of C and .a51 in a simple program. Calling each other from C to get the function written in .a51 or vice-versa is completed. Went through c2asm2c.zip, tested and find that it worked perfectly. However, I encounter some trouble when I need to pass on some variables that need to be manipulated from .a51 to .c My case:- Main code is in .a51. Requires to call a function that adds 20 slightly different 8bit data bytes and then take its average (i.e. by division). Writing the function above in .a51 is a pain due to unavailable 16bit-addition in 8051 done under Keil uV2. My solution thought:- is to write the addition function in C so addition can be done much more easily. Problem:- how do I pass the variables/registers defined in .a51 to the C function to be called from .a51 environment? The C function failed to recognize the similar declared register under .a51 before. Do I need to declare them under a new name OR use the similar name of data registers OR can use some global declaration of data registers. But how? Appreciate some really cool advice if available. Cheers, James
Hi James, My solution is: writing your function and call it in C code, then let the Keil Translate it into ASM code. (You know how to do that, right?) You will know what you need to do in your hand written ASM code to call the C function. The following is just an example:
#include <REG52.H> #define BYTE unsigned char #define WORD unsigned short BYTE xdata RawData[20]; BYTE Average(BYTE * pInputData, BYTE len); void main (void) { BYTE Result; while (1) { Result = Average(&RawData[0], 20); } } BYTE Average(BYTE * pInputData, BYTE len) { BYTE i; WORD sum = 0; for (i=0; i<len; i++) sum += *(pInputData ++); return (sum/len); }
RSEG ?XD?MAIN RawData: DS 20 ; void main (void) RSEG ?PR?main?MAIN main: USING 0 ; SOURCE LINE # 26 ; { ; SOURCE LINE # 27 ?C0001: ; BYTE Result; ; ; while (1) ; SOURCE LINE # 30 ; { ; SOURCE LINE # 31 ; Result = Average(&RawData[0], 20); ; SOURCE LINE # 32 MOV R3,#01H MOV R2,#HIGH (RawData) MOV R1,#LOW (RawData) MOV R5,#014H LCALL _Average MOV Result?040,R7 ; } ; SOURCE LINE # 33 SJMP ?C0001 ?C0002: ; } ; SOURCE LINE # 34 ?C0003: RET ; END OF main ; BYTE Average(BYTE * pInputData, BYTE len) RSEG ?PR?_Average?MAIN _Average: USING 0 ; SOURCE LINE # 38 MOV pInputData?141,R3 MOV pInputData?141+01H,R2 MOV pInputData?141+02H,R1 MOV len?142,R5 ; { ; SOURCE LINE # 39 ; BYTE i; ; WORD sum = 0; ; SOURCE LINE # 41 MOV sum?144,#00H MOV sum?144+01H,#00H ; ; for (i=0; i<len; i++) ; SOURCE LINE # 43 MOV i?143,#00H ?C0004: MOV A,i?143 CLR C SUBB A,len?142 JNC ?C0005 ; sum += *(pInputData ++); ; SOURCE LINE # 44 MOV R3,pInputData?141 INC pInputData?141+02H MOV A,pInputData?141+02H MOV R2,pInputData?141+01H JNZ ?C0008 INC pInputData?141+01H ?C0008: DEC A MOV R1,A LCALL ?C?CLDPTR MOV R7,A MOV R6,#00H MOV A,R7 ADD A,sum?144+01H MOV sum?144+01H,A MOV A,R6 ADDC A,sum?144 MOV sum?144,A ?C0006: INC i?143 SJMP ?C0004 ?C0005: ; ; return (sum/len); ; SOURCE LINE # 46 MOV R7,len?142 MOV A,R7 MOV R5,A MOV R4,#00H MOV R6,sum?144 MOV R7,sum?144+01H LCALL ?C?UIDIV ; } ; SOURCE LINE # 47 ?C0007: RET ; END OF _Average