This is not possible unless we assume some register contains a non-zero value. Proof:
Per Intel 64 and IA-32 Architectures Software Developer’s Manual, March 2013, the logical instructions (5.1.4) are AND, OR, XOR, and NOT, and the shift and rotate instructions (5.1.5) are SAR, SHR, SAL/SHL, SHRD, SHLD, ROR, ROL, RCR, and RCL. Per the problem statement, NOT is excluded but NEG is included.
Inspection of these instructions, excluding NOT, shows that none of them will produce a non-zero result in a register or the carry flag if the input registers and carry flag are all zeros.
We can reasonably assume the stack pointer is not zero in any normal ABI. This allows us to produce -5:
- If DX is not known to be zero, XOR it with itself to set it to zero.
- Use OR to move the stack pointer to another register.
- Apply NEG on the new register. This sets CF.
- Apply RCL on DX (no explicit shift amount, default one bit). This produces 1 in DX.
- Apply NEG, SHL, ROL, ROL on DX. This manipulates the bits to produce -5.