我如何用汇编语言解决这个问题?

时间:2014-02-10 15:06:44

标签: assembly x86 x86-16

我需要将DX寄存器设置为-5,但只需使用逻辑运算符(NOT除外),移位/旋转运算符和NEG,不允许其他指令(不分配常量)。

2 个答案:

答案 0 :(得分:2)

除非我们假设某些寄存器包含非零值,否则这是不可能的。证明:

Per Intel 64和IA-32架构软件开发人员手册,2013年3月,逻辑指令(5.1.4)是AND,OR,XOR和NOT,以及移位和旋转指令( 5.1.5)是SAR,SHR,SAL / SHL,SHRD,SHLD,ROR,ROL,RCR和RCL。根据问题陈述,NOT被排除,但包括NEG。

检查这些指令,不包括NOT,表明如果输入寄存器和进位标志全为零,它们都不会在寄存器或进位标志中产生非零结果。

我们可以合理地假设在任何正常ABI中堆栈指针都不为零。这允许我们产生-5:

  • 如果不知道DX为零,则将其与自身进行异或运算以将其设置为零。
  • 使用OR将堆栈指针移动到另一个寄存器。
  • 在新注册表上应用NEG。这设置了CF。
  • 在DX上应用RCL(没有明确的移位量,默认为一位)。这在DX中产生1个。
  • 在DX上应用NEG,SHL,ROL,ROL。这会操纵位以产生-5。

答案 1 :(得分:1)

我假设使用任何常量被禁止。

(英特尔格式):

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

如果没有STC,我无法立即想到一个简洁的方法。您必须使用某个运算符(NOT除外)将寄存器设置为0以外的其他值,而不使用任何常量。我恶心的方式就像(我的80x86生锈了)

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