Question: At the professional level, for what purpose is reverse software engineering used? What software is targeted and why?

For reasonably complex compiled code that's doing something novel, making meaningful insights into how that code operates via reverse engineering seems like it would be enormously intensive of expertise, labor, and time. In particular, I imagine that hiring competent assembly programmers is extremely difficult and possibly expensive. And yet, I haven't the foggiest idea where entities with the resources to do so would want to spend those resources.

This is my list of possibilities...

1. Writing malware
2. Writing counter-malware
3. Maybe analyzing competitors products?

It's not a great list. What is the reality here? What sort of software justifies the expense to be reverse engineered?

*See the comments on 0xC0000022L's answer for some refinement of the question.*

Answer: 
As a professional Reverse Engineer I have reveresed for:

* Troubleshooting
* Exploit Development
* Malware Analysis
* Implementing badly documented API calls.
* Plagiarism , they knew of an undocumented Kernel call within the Nokia phonebase. Thus we reverse engineerd this and created a program that used this call as well.

Overall reversing increases your knowledge in programming.
I have carried out reverse engineering projects professionally a fair bit. Generally we are commissioned to:

1) Determine how hard it would be to create a crack for some piece of software (by the developers of that software).

2) Understand a specific exploit (in the security sense, e.g. a buffer overflow). In other words, "here's the email we got; tell us what happened", or "here's the exploit. How, *exactly*, does it work and how can we defend against this kind of exploit in future?"

3) Find bugs in a piece of software by examining the binary without reference to the source code, as part of a larger security audit of the code. This is surprisingly useful because some kinds of dangerous behaviour that aren't obvious in code can "leap out" at you in the binary, e.g. complex preprocessor macros causing dangerous behaviour in C/C++. So, counterintuitively, we sometimes use reversing because it's faster. Check out IDA pro and Hopper for the sorts of "quick reversing" features that help in this area - decompiling to pseudocode, finding all calls to X or just searching the string table then finding all references to a dangerous/suspect looking string, and so on. Sometimes just running 'strings' on a binary can give you ideas as to where the bugs might be; following that up with a real, pro reversing tool can help. This isn't restricted to C/C++/Objective C - if we're working in .Net or Java, we'd use .Net Reflector or the Java Decompiler and other environments have their equivalents.

Sometimes we use reverse engineering to help us in a larger project. For instance, we might want to test a component in isolation; to do this without the source code we might want to edit the binary to introduce logging calls or shortcut some behaviour.

Then there's fuzzing, of course, but that's probably not really reversing in the true sense, although it can involve examining code at the assembly level, to understand why the code crashed / where the bug is / whether it's a security problem.

There are many, many reasons why reverse engineering is helpful even in a general development context. In the security field, it's pretty much essential.

In terms of professional development, if you're in the security field and you have good reversing skills, you will probably be at the upper end of the pay scale. You need to be able to do the other stuff, but if you have reversing on your CV - and you can back it up - then getting hired shouldn't be a problem (in the security field at least).