So this is what I've got now: CODE SECTION .data
SECTION .text ALIGN 16 BITS 32
AL_OFF EQU 8 ; Offset from EBP to low bits of a (AL) AH_OFF EQU 12 ; Offset from EBP to high bits of a (AH) BL_OFF EQU 16 ; Offset from EBP to low bits of b (BL) BH_OFF EQU 20 ; Offset from EBP to high bits of b (BH) RES_OFF EQU 24 ; Offset from EBP to result array pointer GLOBAL llmultiply
llmultiply: PUSH EBP MOV EBP, ESP PUSH EAX PUSH EBX PUSH ECX PUSH EDX PUSH EDI PUSH ESI
MOV EAX, [EBP + AL_OFF] MOV EDX, [EBP + BL_OFF] MUL EDX ; AL * BL, EAX = low(AL * BL), EDX = high(AL * BL)
MOV EDI, EAX ; Save low(AL * BL) in EDI MOV ESI, EDX ; Save high(AL * BL) in ESI
MOV EAX, [EBP + AH_OFF] MOV EDX, [EBP + BL_OFF] MUL EDX ; AH * BL, EAX = low(AH * BL), EDX = high(AH * BL)
ADD ESI, EAX ; Add low(AH * BL) to high(AL * BL) ADC ECX, EDX ; Add carry from the previous addition to high(AH * BL) and save in ECX
MOV EAX, [EBP + AL_OFF] MOV EDX, [EBP + BH_OFF] MUL EDX ; AL * BH, EAX = low(AL * BH), EDX = high(AL * BH)
ADD ESI, EAX ; Add low(AL * BH) to high(AL * BL) and low(AH * BL) ADC ECX, EDX ; Add carry from the previous addition and high(AL * BH) to high(AH * BL) and earlier carry, save in ECX
MOV EAX, [EBP + AH_OFF] MOV EDX, [EBP + BH_OFF] MUL EDX ; AH * BH, EAX = low(AH * BH), EDX = high(AH * BH)
ADD EAX, ECX ; Add high(AL * BH), high(AH * BL) and carry to low(AH * BH) ADC EDX, 0 ; Add carry from the previous addition to high(AH * BH)
MOV EBX, [EBP + RES_OFF] MOV [EBX], EDI ; Put low 32 bit of result in array MOV [EBX + 4], ESI ; Put next 32 bit of result in array MOV [EBX + 8], EAX ; Put next 32 bit of result in array MOV [EBX + 12], EDX ; Put high 32 bit of result in array
POP ESI POP EDI POP EDX POP ECX POP EBX POP EAX POP EBP ; restore EBP reg RET ; return It's almost working but there's a carry missing somewhere, for an example: FFFEFFFFFFFFFFFF * FFFF0001FFFFFFFF should be: FFFE0002FFFDFFFE0001FFFE00000001 but I get: FFFE0001FFFDFFFE0001FFFE00000001 So there should be another carry added to EDX. |
|