Visual c++ 带负数和结果的汇编乘法

Visual c++ 带负数和结果的汇编乘法,visual-c++,assembly,x86,inline-assembly,Visual C++,Assembly,X86,Inline Assembly,我是个新来的装配工, 我很难处理负数 #include <stdio.h> void main() { short int mat1[] = {-1,-2, 4,5, 4,-2}; // first array short int mat2[] = {2,0,0,0, 0,2,0,0}; // second array int mat3[1024]; // result array __asm { MOV AX, mat1[0] ;

我是个新来的装配工, 我很难处理负数

#include <stdio.h>
void main() {
    short int mat1[] = {-1,-2, 4,5, 4,-2}; // first array
    short int mat2[] = {2,0,0,0, 0,2,0,0}; // second array
    int mat3[1024]; // result array

    __asm {
        MOV AX, mat1[0] ; mat1[0]:= -1
        MOV BX, mat2[0] ; mat2[0]:= 2
        ; my problem is how i can do this
        ; mat3[0] = mat1[0] * mat2[0] ;
        ; (operation result -> mat3[0] = -2)
    }
}
但是这次手术之后 为什么AX设置为65535而不是-1? 若AX寄存器不正确,那个么如何进行适当的乘法呢? 我很困惑如何处理2的补码


我还有一个问题。 目前,我将IMUL结果移动到数组中

    MOV WORD PTR mat3[ECX*4]+0, AX 
    MOV WORD PTR mat3[ECX*4]+2, DX
我的问题是如何将IMUL结果添加到当前数组[idx]值

如果mat3[当前索引]=0,则该操作是正确的。 但当例如mat3[current index]=-2时,我得到了一个与我期望得到的不同的数字

    ADD WORD PTR mat3[ECX*4]+0, AX 
    ADD WORD PTR mat3[ECX*4]+2, DX

我提前感谢您的帮助

对于8086体系结构,有两条指令可以将两个数字相乘,但可以使用不同的参数:

Val8   DB  12      ; 8-bit variable
Val16  DW  12345   ; 16-bt variable

MUL    BL         ; Unsigned multiply of 8-bit register
MUL    [Val8]     ; Unsigned multiply of 8-bit memory location
MUL    BX         ; Unsigned multiply of 16-bit register
MUL    [Val16]    ; Unsigned multiply of 16-bit memory location

IMUL   BL         ; Signed multiply of 8-bit register
IMUL   [Val8]     ; Signed multiply of 8-bit memory location
IMUL   BX         ; Signed multiply of 16-bit register
IMUL   [Val16]    ; Signed multiply of 16-bit memory location
但是。。。如果它乘以两个变量,第二个变量在哪里?答案是,对于8位乘法,第二个变量总是
AL
,对于16位乘法,第二个变量总是
AX

  • 8位乘法的结果最多可达16位,因此它总是存储在
    AX
  • 16位乘法的结果最多可达32位!哦!8086没有32位寄存器!它将结果存储在哪里?在
    DX:AX
    中。也就是说,它在
    DX
    中存储高16位,在
    AX
    中存储低16位
对于您的代码,您不必将
mat2[0]
移动到
BX
,而只需直接从内存中执行
IMUL
——是的,您应该使用
IMUL
,因为您需要有符号乘法

获得IMUL的结果后,需要将结果存储在
mat3[0]
中。由于不能用一条指令移动
DX:AX
,因此需要两条指令。我不知道您使用的是哪种汇编程序,但通常语法如下:

MOV WORD PTR mat3[0]+0, AX
MOV WORD PTR mat3[0]+2, DX
仔细看上面的内容
mat3[0]
是32位整数,因此不能将16位寄存器移到其中。您需要首先告诉汇编程序将其视为
WORD
(16位)。要存储
DX
中的高16位,需要将它们放在内存中
AX
之后,因此
+2
。(前一行中的
+0
只是为了对称)


别忘了:8086存储其多字节值时,先存储最低有效字节。这意味着您需要存储结果的两部分,如我上面所示。

对于8086体系结构,有两条指令可以将两个数字相乘,但可以使用不同的参数:

Val8   DB  12      ; 8-bit variable
Val16  DW  12345   ; 16-bt variable

MUL    BL         ; Unsigned multiply of 8-bit register
MUL    [Val8]     ; Unsigned multiply of 8-bit memory location
MUL    BX         ; Unsigned multiply of 16-bit register
MUL    [Val16]    ; Unsigned multiply of 16-bit memory location

IMUL   BL         ; Signed multiply of 8-bit register
IMUL   [Val8]     ; Signed multiply of 8-bit memory location
IMUL   BX         ; Signed multiply of 16-bit register
IMUL   [Val16]    ; Signed multiply of 16-bit memory location
但是。。。如果它乘以两个变量,第二个变量在哪里?答案是,对于8位乘法,第二个变量总是
AL
,对于16位乘法,第二个变量总是
AX

  • 8位乘法的结果最多可达16位,因此它总是存储在
    AX
  • 16位乘法的结果最多可达32位!哦!8086没有32位寄存器!它将结果存储在哪里?在
    DX:AX
    中。也就是说,它在
    DX
    中存储高16位,在
    AX
    中存储低16位
对于您的代码,您不必将
mat2[0]
移动到
BX
,而只需直接从内存中执行
IMUL
——是的,您应该使用
IMUL
,因为您需要有符号乘法

获得IMUL的结果后,需要将结果存储在
mat3[0]
中。由于不能用一条指令移动
DX:AX
,因此需要两条指令。我不知道您使用的是哪种汇编程序,但通常语法如下:

MOV WORD PTR mat3[0]+0, AX
MOV WORD PTR mat3[0]+2, DX
仔细看上面的内容
mat3[0]
是32位整数,因此不能将16位寄存器移到其中。您需要首先告诉汇编程序将其视为
WORD
(16位)。要存储
DX
中的高16位,需要将它们放在内存中
AX
之后,因此
+2
。(前一行中的
+0
只是为了对称)


别忘了:8086存储其多字节值时,先存储最低有效字节。这意味着您需要存储结果的两部分,如我上面所示。

无需回答。我早就知道了。另请看。无需回答。我也明白了。也可以看到,OP很明显地使用了C++的32位代码,不局限于运行在8086。imul的两个操作数形式非常方便。此外,所使用的汇编程序是MSVC++的内置程序。据我所知,它很像MASM。@PeterCordes当我第一次看到这个问题时,它有:一个8086标签;只有x86指令;而且只有原来的C++代码。这些最新的编辑。。。改变现状。交给你@麦考德!我真不敢相信我竟然遭受了那样的复制/粘贴错误!谢谢。嘿,我没有检查编辑历史记录。这太糟糕了,这也解释了你为什么这么回答!愚蠢的操作。你不应该在现有问题上添加问题:你应该问一个新问题。注意,你不是在初始化<代码> Mat3——你添加了任何随机值。OP显然使用了来自C++的32位代码,而不限于在8086上运行。imul的两个操作数形式非常方便。此外,所使用的汇编程序是MSVC++的内置程序。据我所知,它很像MASM。@PeterCordes当我第一次看到这个问题时,它有:一个8086标签;只有x86指令;而且只有原来的C++代码。这些最新的编辑。。。改变现状。交给你@麦考德!我真不敢相信我竟然遭受了那样的复制/粘贴错误!谢谢。嘿,我没有检查编辑历史记录。这太糟糕了,这也解释了你为什么这么回答!愚蠢的操作。你不应该在现有问题上添加问题:你应该问一个新问题。请注意,您不是ini