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

mix assmbly and c

Hi all, can any one tell me the way how to mix c and assembly programing....... i know one way of inline programming i.e.

.......
.......
C code....
.....
.....

#pragma asm
........
assembly code....
........
#pragma endasm

but this type of file written cannot be included in any other file......

i have used IAR assembler for other microcontroller, in which writting

asm ("assembly code");

was working perfectly......

i dont know wether keil supports this.... if yes than what prototype file has to be included for this......

Any help is appriciated....

Thanking You,
Pranav Saraswala.

Parents Reply Children
  • I do not know what microresistor (ur) replied, it must have disappeared.

    I say: "have assembly code in an assembly (.a51) module, C code in a c (.c) module, do not mix"

    Erik

  • "it is preferable to write one complete file in assembly as xx.a51 and then call this as a function call in c code."

    Absolutely!

  • "it is more prefferable to write one comlete file in assembly as xx.a51 and than call this as a function call in c code..."

    That's it!

    Inline code is too compiler-specific, and is severely limited. It is actually simpler to write your functions in .A51 files. Get the Assembler manual to check on the syntax, and have a look at some .A51 files to get a grasp on relocated segment declaration, data space declaration and such.

    A few tips:

    1) Use the C51 naming convention for your assembly segments, like ?PR?funcname?filename. Get used with the linker name mangling, you may need to exchange data variables between C and ASM.

    2) Always write relocatable code, and let the linker decide where to put it on the code memory. That means only relative jumps for your loops, and far calls to any other external routines.

    3) Design your function prototypes carefully, using only register parameter passing. Study the C51 register passing and reorder the parameters if needed to fit the rules. It is perfectly possible to call C functions from ASM and vice-versa, if you use the calling conventions correctly.

    4) Document your functions thoroughly. ASM is much less obvious than C, so never assume the reader can read your mind.

    5) Be aware that the compiler may generate code in several different memory models and register accessing options. ASM code will be sensitive to those options.

    Mixed mode C/ASM is a powerful tool. Almost all large projects I did had a least the lower layer functions written in ASM.

  • Thanx for this such useful tips.......

    the only problem i foresee is the passing of variable from the caliing functing (written in c, and function defination written in assembly) to the called function.

    wat i mean......

    suppose in my

    main()
    { c code
    ........
    ........
    assembly_function(some_arguments);
    ......
    ......
    }

    and in the other xx.a51 file

    assembly_function:

    routine written in assembly
    ..........
    ..........
    ..........
    ret

    end

    than for the variable to be passed, should declared as global......

    pls correct me if i am wrong......

    other thing is those thing which appears like ?xx?xxxx.a51?...

    what is all this things ......
    is there any document which gives explanation of all this things.......
    if you are having than pls mail it to me.....
    my mail id is pranav9us@yahoo.com

    Thanks and regards
    Pranav Saraswala

  • "for the variable to be passed, should declared as global"

    Of course.
    But you can still also pass values in parameters, and use the function's return value.

    "is there any document which gives explanation of all this things"

    Of course there is - it's called the Manual.

    There is a chapter specifically titled, "Interfacing 'C' and Assembler" - guess what that's all about...

    You can also do as Erik suggested: write a simple 'C' "skeleton" with examples of all these things (parameter passing, return value, accessing globals), then compile it with the SRC option and look at the generated assembler.
    Then follow the compiler's example.

    The SRC option is, of course, described in the Manual.

  • Jonny Doin,

    your method is waaaaay too complicated.

    write a c module with your assembler function 'sketched' such as this (make sure all 'in' and 'out' poarametres are used:

    U8 func(U8 par1, U16 par2)
    {
      if {par2 == 7)
      {
        return (par1);
      }
      return (0);
    }
    

    compile it with .src and use that as the base for your .a51 module.

    you will have EACH AND EVERY register assignment by the C served on a silver platter.

    Erik

  • "make sure all 'in' and 'out' poarametres are used"

    And the return value, and any accesses to global data

  • I beg to differ.

    Using the SRC directive is nice for learning or for quick templating, but I really do prefer to write ASM code from scratch.

    It is faster, too. If I needed to write a C function with the desired prototype, generate a SRC compilation and work on templated code for EVERY ASM function I wrote, it would have definitely taken longer. The documentation is very clear regarding the register parameter passing and return, you don't need to write a casket function in C for that.

    The name mangling rules and procedure call standard for C51 are simple enough for you to directly create segment names that are correct for the linker, without having the SRC directive to do that for you.

    Exporting and importing data and code is also well described and simple.

    I write a lot of ASM code for interworking with C51, and if it takes longer to write the ASM functions, that is mainly due to longer typed text.

    And there is a benefit when you do write 'pure' ASM: you can usually write better entry/exit code than the compiler. Especially for interrupt handlers.

    "you will have EACH AND EVERY register assignment by the C served on a silver platter."
    Unless you want to save typing time, I see no advantage in this. The parameter loading code really depends on the function body, and unless you write a function body in C, you will probably want to change the parameter loading code generated by the compiler. For example, when passing iteration counts as parameters, I usually simply DJNZ the counter in-place. Another example: I use dual DPTRs a lot, and the compiler has no clue on how and when to load them.

    My motivation for writing ASM code is to use the utmost hand-optimization, else it's better to write it in C.

  • thank you all for this wonderful help........

    but still my one question is unanswered...

    i have used IAR assembler for other microcontroller, in which writting

    asm ("assembly code");

    was working perfectly......

    i dont know wether keil supports this.... if yes than what prototype file has to be included for this......

    if any one knows pls tell me.....

    Thanks and regards,
    Pranav Saraswala

  • "If I needed to write a C function with the desired prototype, ... for EVERY ASM function I wrote, it would have definitely taken longer."

    I presume you are using "prototype" here in the general English sense of the word: dictionary.cambridge.org/define.asp

    Of course, in the specific 'C' sense, you will need a 'C' prototype for each assembler function that you are going to call from 'C'...!

  • "i dont know wether keil supports this..."

    Don't you?
    You started this thread by quoting the Keil ASM and ENDASM pragmas - that is the way that Keil does it.
    See the C51 Manual.

    But the whole point if the answers you have received in this thread is to advise you to avoid doing this!

    Just because a feature is available doesn't mean that it's going to be a good solution!

  • Andy quoted me: "If I needed to write a C function with the desired prototype, ... for EVERY ASM function I wrote, it would have definitely taken longer."

    The above quote generalizes my statement. The full statement was: "If I needed to write a C function with the desired prototype, generate a SRC compilation and work on templated code for EVERY ASM function I wrote...", which is certainly different.

    Explaining further:

    Of course every extern C callable function (whether written in ASM or C or any other compiled language) needs a C prototype to correctly load the passed parameters and get the possible return values. This is taken for granted in our above discussion.

    My comments against using the SRC directive state that in my opinion using the SRC directive to generate ASM code for a given function prototype (meaning a given set of passed parameters) is less than optimal, since you will usually have to rewrite the parameter accessing code from the bank registers, because that code will depend on the function body, which will obviously not be written in C. My point is that the SRC compilation cycle takes more time than simply write the ASM code directly in .A51 files, using the very well documented C51 procedure call standard.

    However, I fully recognize the value of the SRC directive for learning and investigating on how the C compiled code interfaces to other functions.

  • "other thing is those thing which appears like ?xx?xxxx.a51?...

    what is all this things ......
    is there any document which gives explanation of all this things.......
    "

    Yes, they are all in the MANUAL: totallyfuckedup.com/.../Please read the manual.jpg

    Read the C51 manuals, (Compiler, Linker and Assembler).

  • My comments against using the SRC directive state that in my opinion using the SRC directive to generate ASM code for a given function prototype (meaning a given set of passed parameters) is less than optimal, since you will usually have to rewrite the parameter accessing code from the bank registers, because that code will depend on the function body, which will obviously not be written in C. My point is that the SRC compilation cycle takes more time than simply write the ASM code directly in .A51 files, using the very well documented C51 procedure call standard.

    If you do it on a regilar basis and have the "C51 procedure call standard" memorized, I guess you are right.

    However, most of us (I guess) only do this a few times a year and the the old adage "better safe than sorry" do apply. Using the proto/SRC method gives a guaranteed result, using the "C51 procedure call standard" allow for mistakes.

    Erik

  • I totally agree with you. The SRC directive can effectively be a template generator, and have its value as a learning tool, as I have said before.

    I usually write several functions in assembly for any large project in C51, for both space and performance sake. When you are seeking any of those, the SRC templating method is not indicated, due to the reasons discussed above.

    The procedure call standard for C51 is described in the compiler manual, has fixed rules and is very simple. Actually, knowing it helps to write fast C/C function prototypes, not just only ASM/C prototypes.