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

Assembly language

Dear All,

I am very much new to the keil assembler and c language usage in embedde programming. Can anybody help me to sort out some of my problems ?

1. Can I access any of the flags using C language ?

2. If no how can I add assembly code in the '.C' file ?

3. How can I shift the content of a register to right/ left using C ?

These are assumed to be not a processor specific questions.

Please help

Deepak

Parents
  • 1. Yes. Whether or not it's a good idea is a separate question. For example, you can write code like this:

        a = b + c;
        if (CY)
            {
            HandleOverflow();
            }
    

    However, since the C language says nothing about a carry flag, you can't really be sure the carry hasn't been affected by any code generated between those two statements. CY might not have the value it had right after two registers that happened to contain b and c were added. To get such code to work, you wind up relying on particular assumptions about quirks of the code generator implementation, which tend to turn into bugs when you upgrade to some later version of the compiler. In general, I prefer to handle these kinds of details either all in assembler, or all in C. (For example, you can replace the test of CY with a comparison of a and b.)

    2. There are a couple of ways to mix assembler and C. I think the easiest is just to write assembler routines and call them from C. See the section of the manual on calling conventions.

    You can also write C code, and use the SRC directive to turn it into assembler, and then assembler to that file. This, to me, is more trouble than it's worth.

    One thing you might expect that you can't really do is just to drop in inline assembler anywhere in a C function. Lots of compilers let you do this. See point (1) for the reasons why it's often a bad idea.

    3. C doesn't let you control registers, per se. It's the compiler's job to figure out which registers to use. You can shift variables with the left and right shift operators, including the "op equals" form.

    a = a << 4; // shift a left by 4
    a <<= 4;

    Right shifts, per spec, are arithmetic (sign extending) for signed types, rather than logical (shift in zeroes).

    If you need to shift a particular SFR or port, that address would be declared as a variable. If you need to shift a working register, like R0, use assembler (or perhaps re-examine the assumption that you really need to name the particular register).

Reply
  • 1. Yes. Whether or not it's a good idea is a separate question. For example, you can write code like this:

        a = b + c;
        if (CY)
            {
            HandleOverflow();
            }
    

    However, since the C language says nothing about a carry flag, you can't really be sure the carry hasn't been affected by any code generated between those two statements. CY might not have the value it had right after two registers that happened to contain b and c were added. To get such code to work, you wind up relying on particular assumptions about quirks of the code generator implementation, which tend to turn into bugs when you upgrade to some later version of the compiler. In general, I prefer to handle these kinds of details either all in assembler, or all in C. (For example, you can replace the test of CY with a comparison of a and b.)

    2. There are a couple of ways to mix assembler and C. I think the easiest is just to write assembler routines and call them from C. See the section of the manual on calling conventions.

    You can also write C code, and use the SRC directive to turn it into assembler, and then assembler to that file. This, to me, is more trouble than it's worth.

    One thing you might expect that you can't really do is just to drop in inline assembler anywhere in a C function. Lots of compilers let you do this. See point (1) for the reasons why it's often a bad idea.

    3. C doesn't let you control registers, per se. It's the compiler's job to figure out which registers to use. You can shift variables with the left and right shift operators, including the "op equals" form.

    a = a << 4; // shift a left by 4
    a <<= 4;

    Right shifts, per spec, are arithmetic (sign extending) for signed types, rather than logical (shift in zeroes).

    If you need to shift a particular SFR or port, that address would be declared as a variable. If you need to shift a working register, like R0, use assembler (or perhaps re-examine the assumption that you really need to name the particular register).

Children
No data