I'm going to start working on a project where I need to have a decent understanding of Assembly language for the PIC microcontroller's. I'm intimately familiar with C/C++, so I know how to code for the most part, and I have done many projects for the PIC already so I understand the architecture, but have done all my programming for it in 'C'.
Is there a good book or website which does a good job explaining what all the Assembly commands mean and how to do fairly simple tasks (blink LED's, basic math, etc...) for the PIc microcontroller?
Edit: The primary purpose of this post is to request resources for learning Assembly, not debating the merits of C vs Assembly in the PIC's, or whether the PIC is a 'good' microcontroller to use. I am using a PIC18 microcontroller if that makes any difference.
There is more that one PIC architecture, with significantly different instruction sets. Microchip do not have the architectural consistency of Atmel AVR for example. So you need to specify what you are using - PIC12, 16, 24, 32 for example.
So first of all I would suggest avoiding PIC assembler on the basis that what you learn on say a PIC12, that may not be very applicable to a PIC24. Secondly I would avoid using a PIC at all if I possibly could as a software developer - though I concede there are other considerations, and you may have no choice.
What you may have a choice over is not using assembler. While the lower end PICs are not perhaps best suited to C code generation, that's the compiler writer's problem; it is still more cost effective in terms of development time to use C where possible. On the other hand for high volume products, if you can fit the code into a smaller part by using assembler, that may be a factor. Deciding you need assembler before you have tested a C solution is often a 'premature optimisation'. Even if the C implementation fails size or time constraints, you can just call it a prototype, and recode it to meet constraints. Doing than may still be faster than starting assembler coding from scratch and struggling with both design and instruction set at the same time. Tell your boss you'll prototype it in C, then when it meets requirements, no one will want to waste money re-coding it is sone non-portable, unmaintainable assembler code.
Finally to answer your question, assuming you need to get work done quickly and efficiently, use Microchip's examples and app-notes as much as possible, and familiarise yourself with the instruction set from the manufacturers instruction set reference. The instruction set for the lower-end parts is not large. For day-to-day work I like to use an "Instruction set reference card" as an aide-mémoire - it summarises all the essential details of each instruction, usually in a couple of pages - print it double sided and laminate it! ;). Here is a PIC16 example
I would try this: Pic Tutorial
The PICList: http://piclist.com/ .
In particular,
It might be quite a late reply, but you could benefit from this lab course written primarily for learning PIC Assembly through applications.
Check: http://embedded-ju.ucoz.com/
Check the experiments tab, it includes:
Experiment 0 - (Introduction to MPLAB)
Experiment 1 - (Introduction to PIC Assembly Instruction Set)
Experiment 2 - (More on Instruction Set and Modular Programming Techniques)
Experiment 3 - (Basic System Analysis and Design)
3.1. Guide to Hardware I
Experiment 4 - ( LCD - HD44780 )
Experiment 5 - (Keypad)
Experiment 6 - (Using HI-TECH C Compiler in MPLAB) 6.1. PIC Programming with ICD2 Guide.
Experiment 7 - (Timers (Timer0 and Timer2))
Experiment 8 - (USART)
Experiment 9 - (Software PWM & A/D)
It is based on the PIC 16 series, most notably, 16f84A, 16F877A and 16F917 .. the examples are fully commented, and the experiments fully explained.
I am a believer in writing a disassembler. Start with a very simple one or two line program that loads a register with a constant perhaps (gotta read a tutorial or something to learn that step). Assemble it. Save the binary in a format you are capable or willing to write a program to read (intel hex perhaps, or elf if they support that).
Write a program to read the binary file and extract the program then take those bytes and write a disassembler (even if the vendor has a disassembler you should still write one).
Now start iterating the process, learn a new instruction or a new way to use that instruction, one instruction at a time. Write code to disassemble that instruction or option. Try to write assembler to manipulate each of the bits in the instruction.
By the time you get through the instruction set you will know the instruction set better than most people that use it every day, you will know how to write assembler for each of the options for each of the opcodes, you may also learn why this instruction can only address N bytes from its location and others can access anything, or that instruction can only use an N bit immediate and others can use any value. That sort of thing.
I have used this process many times and learned many instruction sets, ymmv. After the first couple-three the process above may only take an afternoon to complete.
EDIT:
The goal here is education not the next great sourceforge project. The output can be as ugly or incomplete as you like you are the only one going to read it.
Note: A generic disassembler for variable length instruction sets can be somewhat difficult, you don't want to linearly disassemble the binary in that case you want to follow all the execution paths. I would avoid it. Taking simple programs that execute somewhat linearly assembling then disassembling is not difficult even on a variable length instruction set. You can learn quite a bit about an instruction set by disassembling and examining the output of a C compiler (or other high level language), if the compiler doesn't have an assembler output option or doesn't have a disassembler you may not get to take advantage of this (unless it is a fixed length instruction set).
Also note once you learn assembler for one processor, the second one is much easier, and so on. The things you need to learn from one to the next often become how big can this jump be, what are the rules on immediates, indirect addressing, basically all the things that are directly tied to examining the opcodes. You can learn it without looking at the opcodes, but you have to rely on the documentation or assembler error messages being high quality.