汇编中的乘法与负数和结果

whe*_*ebz 0 x86 assembly inline-assembly visual-c++

我在组装中相当新,我很难处理负数

#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)
    }
}
Run Code Online (Sandbox Code Playgroud)

ps 这是给我的作业提前谢谢


新问题:

尝试一些组装操作后:

MOV AX, mat1[ECX]   ; eax is 0 and mat1[ecx] is -1
Run Code Online (Sandbox Code Playgroud)

但是在此操作之后,AX 怎么设置为 65535 而不是 -1?如果 AX 寄存器不正确,我该如何进行正确的乘法?我很困惑如何处理 2 的补码。


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

    MOV WORD PTR mat3[ECX*4]+0, AX 
    MOV WORD PTR mat3[ECX*4]+2, DX
Run Code Online (Sandbox Code Playgroud)

我的问题是如何将 IMUL 结果添加到当前的 Array[idx] 值?

在 mat3[current index] = 0 的情况下,操作是正确的。但是当例如 mat3[current index] = -2 时,我的数字与我期望得到的数字不同。

    ADD WORD PTR mat3[ECX*4]+0, AX 
    ADD WORD PTR mat3[ECX*4]+2, DX
Run Code Online (Sandbox Code Playgroud)

我预先感谢您的帮助

Joh*_*ger 5

对于 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
Run Code Online (Sandbox Code Playgroud)

但是......如果它乘以两个变量,那么第二个变量在哪里?答案是第二个变量总是 AL用于 8 位乘法,并且总是 AX用于 16 位乘法。

  • 8 位乘法的结果最多可达 16 位,因此它始终存储在AX.
  • 16 位乘法的结果可以达到 32 位!哦哦!8086 没有 32 位寄存器!它将结果存储在哪里?在DX:AX. 也就是说,它将高 16 位存储在 中DX,将低 16 位存储在 中AX

对于您的代码,您可以直接从内存中直接使用它,而不是移动mat2[0]到 中- 是的,您应该使用,因为您想要一个有符号乘法。BXIMULIMUL

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

MOV WORD PTR mat3[0]+0, AX
MOV WORD PTR mat3[0]+2, DX
Run Code Online (Sandbox Code Playgroud)

仔细看上面的!mat3[0]是一个 32 位 int,因此您不能将 16 位寄存器移入其中。您需要先告诉汇编程序将其视为WORD(16 位)。和存储16位是在DX,你需要把它们 AX在内存中,因此+2。(+0前面的线只是为了对称)。

不要忘记:8086个存储其用最少的显著字节多字节值第一。这意味着您需要存储我上面显示的结果的两个部分。