I need to set DX register to -5 but just by using logical operators(except NOT), shift/rotate operators and NEG, no other instructions allowed(no assigning of constants).

有帮助吗?

解决方案

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.

其他提示

I am assuming use of any constant is banned.

How about (Intel format):

XOR DX, DX       # DX=0
STC              # DX=0, carry flag set
RCL DX, DX       # DX=1
ROL DX, DX       # DX=2
STC              # DX=2, carry flag set
RCL DX, DX       # DX=5
NEG DX           # DX=-5

I can't immediately think of a neat way to do this without STC. You'd have to use some operator (other than NOT) to set a register to something other than 0 without any constants being used. My disgusting way would be something like (and my 80x86 is rusty)

XOR AX, AX      # Now we know IP is not zero, i.e. at least one bit is 1
XOR BX, BX
OR AX, IP
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX
ROL AX, AX
OR BX, AX        # Now we know BX=0xFFFF, as the bit that was 1 has been put
                 # in each of the 16 bits
XOR DX, DX       # DX=0
RCL BX, BX       # DX=0, carry flag set
RCL DX, DX       # DX=1
ROL DX, DX       # DX=2
RCL BX, BX       # DX=2, carry flag set
RCL DX, DX       # DX=5
NEG DX           # DX=-5
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top