2012-11-19 5 views
0

어떻게 할 수있는 두 개의 32 비트 자릿수를 조립하거나 하나의 32 비트 다른 16 비트, 누구 알고리즘을 아십니까?8086 어셈블리 프로그래밍 간단한 알고리즘

data1 dw 32bit 
data2 dw 32bit  
mov ax,data2 
Mul data1 
+0

내장 된'mul' 명령을 구현하는 알고리즘을 원하십니까? – user1666959

+0

또한 http://stackoverflow.com/questions/11513381/assembly-language-masm32-multiplying –

답변

2

먼저, dw은 16 비트 ("단어") 값을 생성하는 데 사용됩니다. 32 비트 값을 보유하지 않습니다. 32 비트 "dword"를 저장하거나 16 비트 값 쌍을 사용하려면 dd을 사용해야합니다.

한 쌍의 32 비트 값을 곱하기 위해 결과는 64 비트가 될 수 있습니다 (예 : 0xFFFFFFFF * 0xFFFFFFFF = 0xFFFFFFFE00000001). 8086의 경우 (80386 이상의 실제 모드 코드뿐만 아니라) MUL 명령어가 있지만 2 16 비트 값을 곱하고 32 비트 결과를 얻는 것으로 제한됩니다. 즉, 각 32 비트 값을 16 비트 값 쌍으로 처리하려고합니다.

A가 A_low (첫 번째 32 비트 수의 최하위 16 비트)와 A_high (첫 번째 32 비트 수의 최상위 16 비트)로 분할되고 B가 B_low와 B_high로 분리되는 경우 같은 방법; 다음 :

A * B = A_low * B_low 
      + (A_high * B_low) << 16 
      + (A_low * B_high) << 16 
      + (A_high * B_high) << 32 

코드는이 (NASM 구문)과 같습니다

  section .data 
first: dw 0x5678, 0x1234 ;0x12345678 
second: dw 0xDEF0, 0x9ABC ;0x9ABCDEF0 
result: dw 0, 0, 0, 0  ;0x0000000000000000 
     section .text 

    mov ax,[first]   ;ax = A_low 
    mul word [second]  ;dx:ax = A_low * B_low 
    mov [result],ax 
    mov [result+2],dx  ;Result = A_low * B_low 

    mov ax,[first+2]  ;ax = A_high 
    mul word [second]  ;dx:ax = A_high * B_low 
    add [result+2],ax 
    adc [result+4],dx  ;Result = A_low * B_low 
             + (A_high * B_low) << 16 

    mov ax,[first]   ;ax = A_low 
    mul word [second+2]  ;dx:ax = A_low * B_high 
    add [result+2],ax 
    adc [result+4],dx  ;Result = A_low * B_low 
             + A_high * B_low 
             + (A_low * B_high) << 16 

    mov ax,[first+2]  ;ax = A_high 
    mul word [second+2]  ;dx:ax = A_high * B_high 
    add [result+4],ax 
    adc [result+6],dx  ;Result = A_high * B_high 
             + A_high * B_low 
             + (A_low * B_high) << 16 
             + (A_high * B_high) << 32 

실제로 나중에 80386 이상을 사용하는 경우는, 그것은 훨씬 더 간단 :

  section .data 
first: dd 0x12345678 
second: dd 0x9ABCDEF0 
result: dd 0, 0   ;0x0000000000000000 
     section .text 

    mov eax,[first]   ;eax = A 
    mul dword [second]  ;edx:eax = A * B 
    mov [result],eax 
    mov [result+4],edx  ;Result = A_low * B_low 
+0

을 보았습니다. Brendan, 감사합니다. 덕분에 많이 도움이되었습니다. –

+0

나는 이것이 오래되었다는 것을 알고있다. 그러나 당신은 8086 버전의 캐리를 놓쳤다. 2 단계와 3 단계 후에 'ADC [결과 + 6], 00h'가 있어야합니다. –

0

제대로 작동하지 않습니다. 당신이 후 캐리가있는 경우 :

adc [result+4],dx  ;Result = A_low * B_low + (A_high * B_low) << 16 ??? 

당신은 [result+6]에서 캐리을 잃게됩니다. [result+4]에 대한 adc [result+6],0을 추가해야합니다.

관련 문제