Assembly 换档和旋转操作不适用于8086教练机套件,为什么?

Assembly 换档和旋转操作不适用于8086教练机套件,为什么?,assembly,x86-16,emu8086,Assembly,X86 16,Emu8086,我一直在对8086教练机套件进行编码。由于某种原因,SHR、SHL、SAL、SAR、ROL、ROR操作无法对其进行编码。如果我写一个像这样的陈述 MOV AX,16 SHR AX,2 它将卡在行SHR AX,2上,就像有语法错误一样。其他换档和旋转操作的情况也类似 我能让它工作的唯一方法是使用CL寄存器 当我把代码改成 MOV AX,16 MOV CL,2 SHR AX,CL 它执行了,但是AX处的值应该是4,而不是5 也适用于此代码 MOV AX,32 MOV CL,2 SHR

我一直在对8086教练机套件进行编码。由于某种原因,
SHR、SHL、SAL、SAR、ROL、ROR操作无法对其进行编码。如果我写一个像这样的陈述

MOV AX,16
SHR AX,2
它将卡在行
SHR AX,2
上,就像有语法错误一样。其他换档和旋转操作的情况也类似

我能让它工作的唯一方法是使用CL寄存器

当我把代码改成

MOV AX,16
MOV CL,2
SHR AX,CL
它执行了,但是
AX
处的值应该是
4
,而不是
5

也适用于此代码

  MOV AX,32
  MOV CL,2
  SHR AX,CL
AX
中的值为
12
,但应为
8

这里发生了什么?我做错什么了吗


注意:请不要告诉我使用DIV&MUL来代替移位操作,因为在大型程序中使用它会变得非常复杂

对于你问题的第二部分,当你在期待
4
时,一旦你把它组装起来并得到
16>>2=5

这是因为您的汇编程序将所有数字都视为十六进制(以16为基数)

如果你有16个十六进制,那就是二进制的0001 0110,那么你移动2次就会得到
0000 0101
也就是5,
0=8
1=4
0=2
1=1

0x16>>2=5

所以您需要指定16位小数
或者使用十六进制基数


0x16=22。如果您想要十进制16,那就是十六进制的
10

当执行类似
MOV AX,16
的操作时,值在内部表示为
0000 0000 0001 0110
。因此,
AX
寄存器的内容现在是
0000 0000 0001 0110

因此,当换档操作
SHR AX,CL
完成时,其中
CL
为2,则
AX
中的值将变为
0000 0101
,即
5

这就是为什么

MOV-AX,16
MOV CL,2
SHR AX,CL

在换档操作后给出了
5

它将卡在行
SHR AX,2
上,就像有语法错误一样。其他换档和旋转操作的情况也类似

如NASM的指令参考中所列,具有立即移位计数操作数的SHR是一条186+指令。因为您似乎正在使用emu8086,所以您的汇编程序和目标机器不支持它

8086仅具有机器代码操作码,用于按
cl
换档和按隐式
1
换档。写入
shr ax,1
将汇编成一条没有立即数的指令,只有用于移位的操作码,隐式计数为
1

不支持其他计数,因为在186之前没有可用的编码


您可以使用
shr
两次移位2,或使用
mov cl,7
/
shr ax,cl
进行更大的计数。(对于像8这样的大计数,在实际8086上执行
mov-al,ah
/
mov-ah,0
可能更快,其中每次移位计数都需要额外的一个周期。)

8086没有立即>1的移位。移位量必须是立即数1,或
cl
。关于您的结果:32h>>2=12,16h>>2=5。因此,您使用的汇编程序似乎默认解释base 16中的直接指令。@Michael:我想知道是不是DEBUG.EXE?我认为所有其他x86汇编程序都默认为十进制。但我认为这并不能解释为什么默认拒绝186和286指令。也许emu8086有一个这样的设置,或者它确实是默认的,而且以前从来没有出现过这样的问题?我说的是AX的数量,不是移位的数量,在CL中,移位的数量在哪里,如果大于1,那是对的,但是为什么16 shr 2的输出是5而不是4是因为这个数字的基数,结果是对的,逻辑不是,我说的是不同的东西。@DavidHoelzer:这只是回答问题的第二部分,关于4对5,但实际上是正确的。我编辑它是为了澄清。谢谢,@Peter Cordes帮助我得出结论