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

Assembly 如何用汇编语言解决这个问题?,assembly,x86,x86-16,Assembly,X86,X86 16,我需要将DX寄存器设置为-5,但只需使用逻辑运算符(NOT除外)、移位/旋转运算符和NEG,不允许使用其他指令(不指定常数) 我假设禁止使用任何常数 (英特尔格式)怎么样: 如果没有STC,我想不出一个简洁的方法来实现这一点。您必须使用一些运算符(而不是NOT)将寄存器设置为0以外的值,而不使用任何常量。我讨厌的方式是(我的80x86生锈了) 这是不可能的,除非我们假设某个寄存器包含非零值。证明: 根据2013年3月《英特尔64和IA-32体系结构软件开发人员手册》,逻辑指令(5.1.4)为an

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

我假设禁止使用任何常数

(英特尔格式)怎么样:

如果没有
STC
,我想不出一个简洁的方法来实现这一点。您必须使用一些运算符(而不是
NOT
)将寄存器设置为
0
以外的值,而不使用任何常量。我讨厌的方式是(我的80x86生锈了)


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

根据2013年3月《英特尔64和IA-32体系结构软件开发人员手册》,逻辑指令(5.1.4)为and、OR、XOR和NOT,移位和旋转指令(5.1.5)为SAR、SHR、SAL/SHL、SHRD、SHLD、ROR、ROL、RCR和RCL。根据问题陈述,不排除NEG,但包括NEG

对这些指令(NOT除外)的检查表明,如果输入寄存器和进位标志均为零,则它们都不会在寄存器或进位标志中产生非零结果

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

  • 如果不知道DX为零,则将其与自身异或以将其设置为零
  • 使用或将堆栈指针移动到另一个寄存器
  • 在新寄存器上应用NEG。这设置了CF
  • 在DX上应用RCL(无显式移位量,默认为一位)。这将产生1英寸的DX
  • 在DX上涂抹NEG、SHL、ROL、ROL。这将操纵位以产生-5

什么CPU?关于汇编的所有问题至少应该在这一点上说清楚。“使用逻辑运算符”
XOR DX,DX
/
或DX,-5
。好了,结束了。@EricPostpischil当然,我也可以猜,但如果问题至少有点精确,不是更好吗?8086,不,Michael,你不能只使用它,它比这更棘手,你必须使用标志,我猜…@EricPostpischil你100%肯定,根本不存在另一个CPU和一个名为“DX”或AX的寄存器,据我记忆所及,IP没有退出。您可以执行xor ax,ax来重置CF,然后执行PUSF
pop ax
pop ax
neg ax
push ax
popf
,您得到了CF=1。剩下的很简单。不,你不能使用
pushf
popf
,因为他说没有其他指令。OP提到允许立即移位量,并且
DX
的初始值为0,因此计算可以减少到3条指令(可能更少?)@ USER 329、380,知道你认为“逻辑运算符”——即列出可用的指令是非常有用的。这里有一个运算符我认为非常有用,我不认为它是逻辑运算符,但也许你是这样做的。我有+1'd,但我认为你需要在第三步之前清除DX;OP没有提供(在问题中)输入时为零。你真的能
SP
进入一个新的寄存器,而不是
IP
?@abligh:OP在一条评论中指出DX最初为零。如果没有,则使用XOR DX将其自身设置为零。指令指针(EIP和IP)在IA-32上无法直接访问。Intel 64使其可以作为RIP访问,但我认为有关DX寄存器的问题不应依赖Intel 64的功能。
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
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