Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly shl-won';t在2字节组(x86)之间移动位_Assembly_Bit Manipulation_Emu8086 - Fatal编程技术网

Assembly shl-won';t在2字节组(x86)之间移动位

Assembly shl-won';t在2字节组(x86)之间移动位,assembly,bit-manipulation,emu8086,Assembly,Bit Manipulation,Emu8086,我有计算阶乘的代码: jmp start ; variables num1 DD 0001h start: mov cl, al factorial_loop: ; cx = ax -> 1 mov al, cl mul num1 ; combine dx and ax into num1 mov num1, dx shl num1, 16

我有计算阶乘的代码:

jmp start

; variables
num1 DD 0001h

start:  mov cl, al

        factorial_loop: ; cx = ax -> 1
            mov al, cl
            mul num1
            ; combine dx and ax into num1
            mov num1, dx
            shl num1, 16
            add num1, ax
        loop factorial_loop

mov ah, 0
int 16h

ret
在代码的开头,我将num1声明为一个4字节的变量。 假设num1被分成两个字节组:num1(左)和num1(右)。 当我移动位时,它们不会从num1(右)移动到num1(左)。
如何解决此问题?

您使用的是16位汇编程序,因此无法使用16位指令移位32位值

shl num1, 16
隐式地与相同(不确定您的汇编器是否支持此语法,但您应该能够理解):

在8086/80286汇编程序中。8086/80286汇编程序中没有32位等价物

由于您似乎正在使用16位代码,因此可以通过以下两种方法之一解决此问题:

1) 声明两个16位字而不是一个32位字,例如

numlo dw 0     ; these are encoded exactly like num1,
numhi dw 0     ; but are declared separately for easier use

...

mov numlo,dx   ; just write to the appropriate 16-bit word
mov numhi,ax   ; without the need to shift at all
2) 或应用手动偏移,例如

mov [num1+2],dx
mov num1,ax

您必须为手动偏移量确定汇编程序的正确语法,尽管根据您的代码,上面的示例应该非常接近。

您使用的是16位汇编程序,因此无法使用16位指令移动32位值

shl num1, 16
隐式地与相同(不确定您的汇编器是否支持此语法,但您应该能够理解):

在8086/80286汇编程序中。8086/80286汇编程序中没有32位等价物

由于您似乎正在使用16位代码,因此可以通过以下两种方法之一解决此问题:

1) 声明两个16位字而不是一个32位字,例如

numlo dw 0     ; these are encoded exactly like num1,
numhi dw 0     ; but are declared separately for easier use

...

mov numlo,dx   ; just write to the appropriate 16-bit word
mov numhi,ax   ; without the need to shift at all
2) 或应用手动偏移,例如

mov [num1+2],dx
mov num1,ax

您必须为手动偏移量的汇编程序确定正确的语法,尽管上面的示例应该非常接近,基于您的代码。

这是什么汇编程序?我使用emu8086(x86),即使它起作用,但这不是积累32位产品的方式。8086没有32x32=>32的乘法运算,只有16x16=>32。在使用它之前,您只需设置AX的低8位。这是什么汇编程序?我使用emu8086(x86),即使它起作用,但这不是32位乘积的累积方式。8086没有32x32=>32的乘法运算,只有16x16=>32。在使用之前,您只需设置AX的低位8位。在real 8086中,唯一的移位指令是按1移位和按CL移位。因此,对于1以外的移位计数,您需要将计数放在CL中。(有关insn在何时引入的详细信息,请参阅旧版NASM手册的本附录:)。(和中其他有用的链接。@PeterCordes您完全正确,但在real 8086中,mul也不支持内存操作数,因此此仿真器的指令集显然比real 8086更灵活,而且我认为在指令汇编时提及这两个限制都不重要。您有这一说法的来源吗?使用
/r
字段作为额外的操作码位,使模式和
/m
位像往常一样可用于对寄存器或内存操作数进行编码,就像
添加r/m16、imm16
和大多数其他指令一样,只有一个显式操作数。(386
imul r16、r/m16、imm16
是使用VEX编码的BMI/BMI2整数指令之前的少数例外之一).我不记得在8086中听说过一些指令不支持ModRM字节的所有常规编码。在real 8086中,唯一的移位指令是按1移位和按CL移位。因此,对于除1以外的移位计数,您需要将计数放入CL。(参见NASM手册旧版本的本附录,了解在以下时间引入insn的详细信息:)。(和中其他有用的链接。@PeterCordes您完全正确,但在real 8086中,mul也不支持内存操作数,因此此仿真器的指令集显然比real 8086更灵活,而且我认为在指令汇编时提及这两个限制都不重要。您有这一说法的来源吗?使用
/r
字段作为额外的操作码位,使模式和
/m
位像往常一样可用于对寄存器或内存操作数进行编码,就像
添加r/m16、imm16
和大多数其他指令一样,只有一个显式操作数。(386
imul r16、r/m16、imm16
是使用VEX编码的BMI/BMI2整数指令之前的少数例外之一)。我不记得在8086中听说过一些指令不支持ModRM字节的所有常规编码。