0
\$\begingroup\$

I have heard that earlier PICs that are quite tiny are to be programmed using assembly and not C. Later PICs had hardware instructions to make them easy to be programmed via C language. However, I am not sure what this means.

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Early PICs had a stack that was only 3 addresses deep. That would be problematic for C code. \$\endgroup\$ – user_1818839 Aug 6 '20 at 21:51
  • \$\begingroup\$ So which PICs are the ones that must be programmed in assembly only, does C compatibility start with PIC10? \$\endgroup\$ – Quantum0xE7 Aug 6 '20 at 21:53
  • \$\begingroup\$ Early PIC's like the 17C756 that I used for years were often programmed in assembler, with a custom version of 'C' available. Often custom versions of C had little or no stack management or floating-point math. \$\endgroup\$ – user105652 Aug 6 '20 at 21:56
  • 1
    \$\begingroup\$ Your title is inconsistent with the text of your question. Could you edit your title for accuracy and brevity, please? \$\endgroup\$ – TimWescott Aug 6 '20 at 21:57
  • 1
    \$\begingroup\$ Pretty much all the 8-bit PICs have a machine architecture that is a poor fit to C -- a truly ANSI compliant C compiler, used with code written good portable style, compiles code that is slow and bulky compared to the "almost C" implementations that I've used on the PIC. The biggest bummers were the Harvard architecture (which puts constants and variables in fundamentally different memory spaces) and, on some chips, the weird stack limitations. It's lovely for itty bitty programs in assembly, though. \$\endgroup\$ – TimWescott Aug 6 '20 at 22:01
2
\$\begingroup\$

Later PICs had hardware instructions to make them easy to be programmed via C language. However, I am not sure what this means.

Early PICs had limited memory and were quite slow so the code had to be small, efficient, and not waste precious RAM. It is possible to get close to assembler efficiency with a well-tuned C compiler by using various tricks, but with a small program it's often easier to just write it in assembler. With larger programs the advantages of C come to the fore (source code more compact and easier to read, more portable, better type checking, less chance of making silly errors etc.).

However early PICs also had hardware limitations that made it difficult for C compilers to produce good code, including:-

  • Strictly 8 bit operation. The default integer size in C is normally at least 16 bits. Using 16 bit integers wasted precious RAM and dramatically slowed down processing. C's poor handling of integer overflow can make working in 8 bits tricky.

  • No user stack. The stack on early PICs was only used for storing return addresses and could not be accessed by program code. This made local variables and re-entrant functions harder to implement and less efficient.

  • Very small return stack. Some early PICs only had a 2 level stack. This severely limited the ability to nest subroutines.

  • Limitation on code placement. Some PICs could only call subroutines in even 256 byte ROM pages (eg. on PIC12C508 all subroutines have to be placed in the first 256 bytes of ROM).

  • No interrupts. Some PICs had to do everything by polling, so cycle counting was the norm for getting accurate timing. This is not compatible with C, which cannot guarantee that code will use any specific number of cycles.

  • Inefficient access to data in ROM. The 'Table Read' instruction reads a data byte by doing a 'computed goto' to a 'RET N' instruction that returns the immediate data byte embedded in the instruction. This is slow, wastes ROM space and cannot cross a 256 byte page boundary.

  • Paged RAM and I/O register access. PIC12/16 chips often have several banks because there is not enough memory space for linear addressing. The compiler may not be able to determine which bank is currently selected at run time, so has to insert more bank switching instructions than might be necessary with carefully crafted machine code.

\$\endgroup\$
2
  • \$\begingroup\$ Since small PICs cost quite little, I guess no one uses the PICs that are so tiny that we must write assembly code to be able to run them efficiently? \$\endgroup\$ – Quantum0xE7 Aug 7 '20 at 23:05
  • \$\begingroup\$ The smallest PICs (eg. PIC10F322 in SOT23-6) still are worth programming in assembly code. Even larger chips sometimes need asm for best efficiency. I used an ATmega1284 as a ROM emulator that needed the entire 16k RAM for data. Programed it in asm with all variables stored in registers and no stack, and it had just enough speed to do the job. This replaced a more expensive design that used several chips, so it was worth the effort. \$\endgroup\$ – Bruce Abbott Aug 8 '20 at 0:53
4
\$\begingroup\$

Define earlier. The 16F series is from the earlier days (20 years ago?) Back then we would write MP-ASM and C code, then I found a C++ compiler for it too.

It all depends on what you are writing and how efficient the compiler is for it. The Hi-Tech C compiler, which I believe Microchip purchased (the whole company), was pretty darned efficient, and made really small hex files. True, you can make smaller code by hand writing assembly, but then how long do you want to spend writing code vs. making the project as a whole?

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Plus: Writing C is usually easier to "reason about", i.e. when reading through it, you're more likely to spot logical errors in "business logic" (might be different for things like setting up hardware control registers). "Reasoning about your code" is what is necessary to write better software, in the end. \$\endgroup\$ – Marcus Müller Aug 6 '20 at 22:03
  • \$\begingroup\$ 20 years ago? I have a PIC 16 series datasheet from about 1983, when they were still a General Instruments product. \$\endgroup\$ – user_1818839 Aug 6 '20 at 22:23
  • \$\begingroup\$ @BrianDrummond Ha! Well we can all date ourselves. I think I was in about 3rd grade then. :) \$\endgroup\$ – Aaron Aug 7 '20 at 0:00
  • \$\begingroup\$ Since small PICs cost quite little, I guess no one uses the PICs that are so tiny that we must write assembly code to be able to run them efficiently? \$\endgroup\$ – Quantum0xE7 Aug 7 '20 at 23:04
2
\$\begingroup\$

Your title does not quite agree with the text, so I'll refer to the text.

It was possible to use a cross compiler even on the earliest PICs, but there were significant compromises in the C you could write and in the generated code. Hitech C (now owned by Microchip) supported even the tiniest PIC, as does XC8. The paged memory, limited stack and so on made it difficult to write much in the way of serious C. There are usually ways around some of the limitations but it's typically an unpleasant choice. Particularly when you have only 16 bytes of RAM total and only 256 words of program memory total (PIC10F200).

They added registers and some instructions to better support C, such as the ability to read constants from program memory.

I would put it a bit differently, you could either write, at most, a fairly trivial program in C for the tiniest micro (perhaps with a lot of head scratching to try to work around the compiler limitations) or you could use it as it was intended, in assembler and do some fairly interesting and complex things (though the lack of interrupts in the smaller PICs was a pain).

Later micros such PIC24 series were designed with the compiler requirements in mind so that emitted code could be reasonably efficient and come closer to standard C.

\$\endgroup\$
2
  • \$\begingroup\$ Since small PICs cost quite little, I guess no one uses the PICs that are so tiny that we must write assembly code to be able to run them efficiently? \$\endgroup\$ – Quantum0xE7 Aug 7 '20 at 23:05
  • \$\begingroup\$ Billions and billions of small PICs and their brethren from suppliers such as Elan, Holtek and many others are sold each year for appliances, automotive, power tools and so on. The work it takes the programmers or engineers is a negligible consideration if they can save a few pennies per unit. \$\endgroup\$ – Spehro Pefhany Aug 8 '20 at 0:41
1
\$\begingroup\$

I've never heard that (and it doesn't sound like it makes sense to me - every turing-complete instruction set can be a target of C), but what I guess is that:

C is a language that uses functions that you can call, and return from. To enable that, many architectures use what is called a stack, ie. kind of a pile of memory on which every function can put their "working scrapbook" on top, and when it returns, it just "walks back" the height of the stack.

This can be very elegantly be used if your hardware has a special stack pointer register.

Another thing (I don't know whether that is the case for any of the multiple PIC instruction sets) is adding hardware "call the function at address X" instructions, which inherently saves the position from which we jumped into the function (typically on top of the stack), and another "return" instruction, which jumps back to the saved location.

Again, neither is strictly necessary for a machine to be a target for C! For example, WASI (the instruction set/ABI for the WASM virtual machine that allows your browser to run bytecode instead of just JavaScript) doesn't have a "proper" stack. And C is definitely among the languages you can run on that.

However, if you don't have a hardware stack, and only very few registers, and limited RAM, then you're getting into trouble very quickly, because you simply always need to hold on to more data than you can. You might not be able to fit a C program that software-builds all the needed functionality into the program memory of one of the smallest PICs, either.

\$\endgroup\$
1
  • \$\begingroup\$ Since small PICs cost quite little, I guess no one uses the PICs that are so tiny that we must write assembly code to be able to run them efficiently? \$\endgroup\$ – Quantum0xE7 Aug 7 '20 at 23:04
1
\$\begingroup\$

There are the older pics then the pic32 which is completely unrelated and is a mips core. Naturally MIPS C compilers exist. The older pics had C compilers as well, but the instruction sets are not very C friendly, and compiled code has some bulk to it (in general). End of the day it is up to you but a C compiler for the older pic12's etc never made sense to me, the best optimizer in the world would still be inefficient and the platform is so limited.

Or you can certainly take the path of compile first then hand tune the asm where desired/needed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.