This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

call an ASM function from a C function

I wrote a C extension file program where my function is declared with C langage with parameters and writen in ASM langage:

int MyFunc(int param1, int param2)
{
#asm
...
...
#endasm
}

From other files, the call is working but I have WARNING in compilation of my assembly file on param1 and param2 because I don't use them directly but I use register R4 to R7.

The program is working but I don't understand how can I write the program to don't have any warning.

  • I use a different way of mixing C and assembler. I write the assembler routines in a separate file/module (*.A51) and set up a header file with the function prototypes for being included into C programs instead of using the "inline assembler".

    This is pretty simple. I usually write a "fake" C file, that contains the function definitions and the variables. Then I put
    #pragma SRC
    into the first line. This directs the compiler to generate an assembler listing instead of the object file.

    This generated assembler files includes the description of the location of the function calling parameters and all the segments and variable allocation and public declaration.

    Then I copy this file to be the "frame" of the assembler routine I want to write. Finally I set up the header file for C.

    I have done that with a function set for controlling an LCD display and it works fine. I sure have to change the calling parameters a bit, since I originally didn't use the same registers like C51 for the function calls.

    Take care
    Sven

  • If you want help with Compiler messages, please be sure to tell us precisely what message it is that's bothering you!

    Presumably, you're getting "Unused local variable" or similar warnings for param1 & param2?

    As you say, you don't actually use these symbols, so it's not that surprising!

    However, I find this message rather misleading; I think it'd be more helpful if Keil gave distinct warnings which specifically stated whether it's an usused local variable, or an unused parameter.

    It would also be useful if there were some way to specify that a particular symbol is known to be "unused"
    (to be fair, this is a perennial problem, and I don't know of a compiler that handles it well).

  • in fact with dummy assigments at the beginning of the function warnings disappear

    int MyFunc(int param1, int param2)
    {
    param1 = param1;
    param2 = param2;
    #asm
    ...
    ...
    #endasm
    }

    it's still warning on non-return value...

  • could you describe me your use with a theoric example using file1.c and file2.a51 where a return function with parameter is writen in a51 file and the C call function is in the C file?

    Thank you for your help,
    Yann

  • Yes, I've seen that trick before, but some compilers actually generate code for the useless statements!
    With some others, this just gives you a different warning, "code with no effect" or something!

  • First you have to set up some kind of fake C file... here I will call it "xxx_prot.c" because you only set up kind of function skeletons.

    It looks like this:
    xxx_prot.c:
    #pragma SRC

    unsigned char func1( unsigned char parameter ) {
    unsigned char loc_var_func1; // some local variable

    loc_var_func1 = 0;
    return loc_var_func1;
    }

    void func2( void ) {
    }

    Then you compile this file (the SRC pragma is important). Instead of an object file, you get a file called xxx_prot.src.

    It is an assembler program and looks looks like this:
    NAME XXX_PROT

    ?PR?_func1?XXX_PROT SEGMENT CODE
    ?XD?_func1?XXX_PROT SEGMENT XDATA OVERLAYABLE
    ?PR?func2?XXX_PROT SEGMENT CODE
    PUBLIC func2
    PUBLIC _func1

    RSEG ?XD?_func1?XXX_PROT
    ?_func1?BYTE:
    parameter?040: DS 1
    ; #pragma SRC
    ;
    ; unsigned char func1( unsigned char parameter ) {

    RSEG ?PR?_func1?XXX_PROT
    _func1:
    USING 0
    MOV DPTR,#parameter?040
    MOV A,R7
    MOVX @DPTR,A
    ; SOURCE LINE # 3
    ; unsigned char loc_var_func1; // some local variable
    ;
    ; loc_var_func1 = 0;
    ; SOURCE LINE # 6
    ;---- Variable 'loc_var_func1?041' assigned to Register 'R7' ----
    CLR A
    MOV R7,A
    ; return loc_var_func1;
    ; SOURCE LINE # 7
    ; }
    ; SOURCE LINE # 8
    ?C0001:
    RET
    ; END OF _func1

    ;
    ; void func2( void ) {

    RSEG ?PR?func2?XXX_PROT
    func2:
    ; SOURCE LINE # 10
    ; }
    ; SOURCE LINE # 11
    RET
    ; END OF func2

    END

    As you can see the parameters are commented and the required segments already have the right names and what
    you need to be imported by other c-files is declared public.

    You can copy this into your destination assembler file (e.g. xxx.a51) and "fill in" your code.

    Then you write a header file (e.g. xxx.h), like if you would do that for the xxx_prot.c.

    That's it. It is not very difficult. I woudl recommend to name the "prototype c file" different from the actual assembler file.