具有负数和结果的装配中的乘法

时间:2016-09-21 11:25:54

标签: 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] ; 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)
    }
}

P.S。这是我的作业 提前谢谢

新问题:

尝试一些装配操作后:

MOV AX, mat1[ECX]   ; eax is 0 and mat1[ecx] is -1

但是在这个操作之后 为什么AX设置为65535而不是-1? 如果AX寄存器不正确,我怎样才能进行适当的乘法运算? 我很困惑如何处理2的补充。

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

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

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

这个mat3 [当前索引] = 0,操作正确。 但是当例如mat3 [当前指数] = -2时,我的数字与我期望得到的数字不同。

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

我提前感谢您的帮助

1 个答案:

答案 0 :(得分:3)

使用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位int,因此您无法将16位寄存器移入其中。您需要告诉汇编程序首先将其视为WORD(16位)。要存储DX中的 16位,您需要将 AX之后的放在内存中,因此{{1} }。 (之前行中的+2仅用于对称)。

不要忘记:8086存储其多字节值,其中最低有效字节第一个。这意味着您需要存储结果的两个部分,如上所示。