Sam Williams wrote: >I am attempting to create a test environment that will >answer the question regarding the viability of using C vs >assembler for PIC programming. I know most of the >arguments, but I was wondering if anyone had any >references to hard data that had been accumulated using a >large number of test programs. I know the request may >sound stupid, but company management currently believes >that C would give us a better opportunity for finding >programmers. Code size could be the caveat. We are >developing code for embedded aerospace control >applications which means we have very tight constraints >on component selection and use. > >Any help would be greatly appreciated. I don't know where you could find 'hard' data comparing assembly language to C except from compiler vendors. I doubt that such data would provide much useful information anyway since so much depends on the nature of the tests and applications. If the 'hand-coded' assembly is produced by translating a C program, for example, then approaches which are possible only in assembly language would be overlooked. Assembly language often suggests the use of different algorithms than C. If such algorithms are used then more efficient and tightly controlled use of resources can often be achieved. I have encountered applications where I was unable to come up with an acceptable solution using a C compiler but was able to find a good solution coding in assembly language. The last time I attempted to use a C compiler for a PIC was about 3 years ago when I was working on a very large project. I thought that dropping $700 on the compiler would be a good investment because of the time it would save ... I ended up wasting a lot of time and going back to assembly language in the end because the design required tight use of resources and I could not find a way to fit the design into the selected part using the C compiler. Techniques that I could only implement in assembly (and not just inline assembly) allowed the design to fit in the selected part with room to spare. Today's PIC C compilers are probably much better (I don't know because I haven't touched one since that bad experience). I personally found that assembly language is actually a lot less time consuming to program in than C if the task demands efficient use or tight control of processor time, stack space, or memory. Note that I do spend a great deal of time programming in C++ for larger machines so I really do appreciate the benefits of working at a higher level of abstraction when resources are plentiful. I just found that the PIC compilers I tried to use would not allow me to apply certain techniques that I had grown accustomed to using in assembly language. Some examples of PIC assembly-language techniques that I could not find a suitable substitute for in the then 'state-of-the-art' C compilers were: 1). Dispatch tables ... jumping to a handler based on the contents of a register: TRANSMIT MOVLW HIGH TXJMPTBL MOVWF PCLATH MOVF TX_STATE,W ADDLW LOW TXJMPTBL BTFSC ALUSTA,C INCF PCLATH,F MOVWF PCL TXJMPTBL GOTO TX_0 GOTO TX_1 GOTO TX_2 etc ... TX_0 ... (handler for transmit state 0) TX_1 ... (handler for transmit state 1) etc ... This is something I definitely expected the C compilers to at least come close to supporting but was disappointed by ... in ANSI C the following would work in a similar fashion (using more stack space but otherwise doing the same thing): function protocols and table declaration: void tx_1(void); void tx_2(void); void tx_3(void); etc... void (*tx_functions[]) (void) = { tx_1, tx_2, tx_3, etc... }; then, to do the dispatch: tx_functions[tx_state](); But, unfortunately the compilers I had available back then would not do this. Do modern C compilers for the PIC allow arrays of pointers to functions (or better yet labels that are not necessarily function entry points)? Is there a way to GOTO the computed address rather than CALL it? It would also be cool if a C compiler could optimize code so that the following would dispatch control through a table: switch(tx_state) { case 0 : (code for tx_0) case 1 : (code for tx_1) case 2 : etc... } The compilers I worked with just produced code like: MOVF tx_state,W BTFSC STATUS,Z GOTO tx_0 XORLW 1 BTFSC STATUS,Z GOTO tx_1 XORLW 1 ^ 2 BTFSC STATUS,Z GOTO tx_2 etc... which burned up way more ROM space and processor cycles than our application allowed (the table was rather large and the timing critical). 2). Jumping to a common function entry or cleanup point to save ROM space and stack levels: DO_ONE_THING BSF PORTC,3 GOTO DO_THING DO_SIMILAR_THING BCF PORTA,0 DO_THING ... (common code) RETURN 3). Tightly controlling timing by counting clock cycles and balancing all branches of a loop so that its cycle timing is constant. 4). Avoiding the per-call bank switching ROM space overhead for calling functions in other pages of ROM by placing hooks in the same bank as the caller and making the hooks flip the bank select bits. Do modern compilers automatically do this upon request (a "save memory" versus "save time" optimization)? It seems like they should but the ones I used a few years ago didn't. They would always produce code like: BSF PCLATH,n CALL FUNC_IN_HIGH_BANK BCF PCLATH,n regardless of how many times a call to that function occurred. There are several other examples I ran across by comparing the assembly output from the C compiler with what I would have done if I had hand-coded it. My best C implementation required more memory space and stack space than the PIC microcontroller had available. My assembly language implementation, however, fit with plenty of room to spare and packed in several features I was considering leaving off when I was trying to get the C implementation to fit. I truly would be interested in a C compiler that could allow a good programmer to produce object code that compares favorably with hand-coded assembly language (done by a competent coder, of course, and not patterned after an algorithm that was designed for implementation in C). I am not holding my breath. Some things are best done at a low level of abstraction. C is very useful for many PIC projects and definitely has its niche. To attempt to apply it to situations where resources must be tightly controlled, however, is like attempting to trim a Bonsai tree with a chainsaw. It is just not the most appropriate tool for such jobs. Ken