The Intel manual (I am specifically looking in "Intel Architecture Software Developer’s Manual Volume 2: Instruction Set Reference", ) says, about the lock prefix:
The LOCK prefix can be prepended only to the following instructions and to those forms of the instructions that use a memory operand: (list includes xchg...)
Note that it says "ONLY TO THOSE FORMS OF THE INSTRUCTION THAT USE A MEMORY OPERAND" (excuse the caps lock - it makes it easier to see where the quote ends and my comment starts :) ). You are trying to lock an instruction that doesn't need to be locked, as it is only operating on registers on the core it is being executed on.
It further says:
"The XCHG instruction always asserts the LOCK# signal regardless of the presence or absence of the LOCK prefix."
and, regarding exceptions, it is the same for all operating modes:
"If the LOCK prefix is used with an instruction not listed in the “Description” section above. Other exceptions can be generated by the instruction that the LOCK prefix is being applied to."
So, if you are adding the LOCK prefix to any instruction that does not access memory, you will generate an exception (in fact, as the manuals say that the exception is generated but don't say only in certain environments, I would suggest that the Intel docs are wrong - it should obviously say it would generate an exception only in SMP environments, if that is the case :). If this is not your problem, please post the actual code you are having the problem with (I am assuming the problem is locking a reg to reg version of xchg as that is the code example you showed...).
Finally, in reply to the last question. Yes, the code you wrote without LOCK is safe, as even if you are accessing memory with it, xchg will lock the memory automatically, so if modifying memory in a multi-processor environment, you can safely use xchg without a prefix.