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

Big ERROR in C166 4v20

Hi,

there is huge misunderstood in C166, just try this:

#pragma code // and

char * cptr; // and this:


cptr[-1]=*cptr++;

and look at the assmbled machine code.
and ... have a lot of fun ...

  • Actually there are 2 big errors in your code.

    The first is that you used cptr & cptr++ in the same expression (actually between 2 sequence points). Since it is the compilers choice as to which term to evaluate first, you can see that this is undefined expression in C.

    The second is that the index is of type size_t, which is 0..65535 for Keil. So the -1 <=> 0xffff was converted to 65535 <=> 0xffff.

    Actual your best bet is to work backwards like:

    cptr = &a[ sizeof(a) - 1 ]
    for( i = sizeof(a) - 1; i != 0; --i )
    {
      c = *cptr
      *--cptr = c;
    }
    

  • "The first is that you used cptr & cptr++ in the same expression (actually between 2 sequence points)."

    See the following for a discussion of a similar "problem:"
    http://www.keil.com/forum/msgpage.asp?Offset=-1&MsgID=2016

  • To see what really is going on, I would suggest to have a look at the following piece of code:

    void main(void)
    {
    	char xhuge* cptr = (char xhuge*)*(long*)0; // just to see what registers are allocated for cptr
    	cptr[-1]=*cptr++;
    }
    
    You will see that cptr is incremented before evaluation of 'cptr[-1]' and after evaluation of '*cptr', which is perfectly fine. 'cptr[-1]' subtracts 1 from cptr to obtain the right address, which is all right too. What can also be seen is LOTS of redundant MOVs and lack of optimization (the compiler could have used the initial value of cptr in 'cptr[-1]' instead of incrementing the pointer and decrementing it back). I have seen such extravagant use of registers and, consequently, redundant MOVs far too often.

  • Should I need some special addendum for CA166 ?

    This line will produce correct code:
    *cptr++=cptr[1];

    And I sholud say that default memory model was far data.

    Could you say why other compilers work fine with this problem ? (gcc)

  • I will only say that:

    I advice you to check how work more professional compilers (and not so expensive) like GNU CC (well known as "gcc" i.e. under linux) and if you will ever port some source I wish you good luck, by the way, this statement will work fine:

    *cptr++=cptr[1];

    so don't tell me those b.. s.. about cptr's in one line.
    and my error was that I didn't say about default memory model.

  • Thank you. I have forgotten to say about default memory model - sorry for your inconvenience.

    Let suppose that you are porting some source code which works fine under gcc.
    Should C166 generate some warning ? What do you think about it ?

    (line : "*cptr++=cptr[1];" will produce correct code)

    Best regards

  • Hi Jon.

    I decided to send another interesting example. And also I have also decrypted the name of "CA166" which means C in 42.0% and the rest is assembler in C so all of us should be grateful for that C inserts "nop" after changing CP or DPPx.


    C166 COMPILER V4.20c, BS 01/09/2002 11:28:53 PAGE 1


    C166 COMPILER V4.20c, COMPILATION OF MODULE BS
    OBJECT MODULE PLACED IN bs.OBJ
    COMPILER INVOKED BY: C:\KEIL\C166\BIN\C166.EXE bs.c MOD167 DEBUG

    stmt lvl source

    1 #pragma code
    2
    3 struct again
    4 {
    5 char a;
    6 };
    7
    8 void bs_test(char * cptr)
    9 {
    10 1 cptr[-1]=*cptr++;
    11 1 *cptr++=cptr[1];
    12 1 }
    13
    14 void bs_come_back(struct again * saptr)
    15 {
    16 1 saptr[-1]=*saptr++;
    17 1 }
    C166 COMPILER V4.20c, BS 01/09/2002 11:28:53 PAGE 2

    ASSEMBLY LISTING OF GENERATED OBJECT CODE


    ; FUNCTION bs_test (BEGIN RMASK = @0x4160)
    ; SOURCE LINE # 8
    ;---- Variable 'cptr' assigned to Register 'R8' ----
    ; SOURCE LINE # 10
    0000 99A8 MOVB RL5,[R8+]
    0002 E4A8FFFF MOVB [R8+#0FFFFH],RL5
    ; SOURCE LINE # 11
    0006 F4C80100 MOVB RL6,[R8+#01H]
    000A F058 MOV R5,R8
    000C 0881 ADD R8,#01H
    000E B9C5 MOVB [R5],RL6
    ; SOURCE LINE # 12
    0010 CB00 RET
    ; FUNCTION bs_test (END RMASK = @0x4160)

    ; FUNCTION bs_come_back (BEGIN RMASK = @0x41D0)
    ; SOURCE LINE # 14
    ;---- Variable 'saptr' assigned to Register 'R8' ----
    ; SOURCE LINE # 16
    0012 F048 MOV R4,R8
    0014 0881 ADD R8,#01H
    0016 F068 MOV R6,R8
    0018 2861 SUB R6,#01H
    001A E017 MOV R7,#01H
    001C ?C0001:
    001C E964 MOVB [R6],[R4+]
    001E 0861 ADD R6,#01H
    0020 2871 SUB R7,#01H
    0022 3DFC JMPR cc_NZ,?C0001
    ; SOURCE LINE # 17
    0024 CB00 RET
    ; FUNCTION bs_come_back (END RMASK = @0x41D0)



    MODULE INFORMATION: INITIALIZED UNINITIALIZED
    CODE SIZE = 38 --------
    NEAR-CONST SIZE = -------- --------
    FAR-CONST SIZE = -------- --------
    HUGE-CONST SIZE = -------- --------
    XHUGE-CONST SIZE = -------- --------
    NEAR-DATA SIZE = -------- --------
    FAR-DATA SIZE = -------- --------
    XHUGE-DATA SIZE = -------- --------
    IDATA-DATA SIZE = -------- --------
    SDATA-DATA SIZE = -------- --------
    BDATA-DATA SIZE = -------- --------
    HUGE-DATA SIZE = -------- --------
    BIT SIZE = -------- --------
    INIT'L SIZE = -------- --------
    END OF MODULE INFORMATION.


    C166 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)