; File: biadd.asm ; ; Impelementation of BI_Add in assembly language for the ; BigInt class. (See bigint.h and bigint.cpp.) section .text global BI_Add global BI_Add__FR6BigIntRC6BigIntT1 BI_Add: BI_Add__FR6BigIntRC6BigIntT1: push ebp ; set up stack frame mov ebp, esp push ebx ; save registers push esi push edi ; address of sum = [ebp+8] ; address of op1 = [ebp+12] ; address of op2 = [ebp+16] mov edi, [ebp+8] ; &sum mov edi, [edi] ; sum.ptr mov esi, [ebp+12] ; &op1 mov ecx, [esi+4] ; op1.len mov esi, [esi] ; op1.ptr mov ebx, [ebp+16] ; &op2 mov edx, [ebx+4] ; op2.len mov ebx, [ebx] ; op2.ptr cmp ecx, edx ; which is shorter? jae Add_Cont1 xchg ebx, esi ; swap shorter to ebx, edx xchg ecx, edx ; After this (esi,ecx) has the longer number ; and (ebx,edx) has the shorter number Add_Cont1: push ecx ; remember longer number for later mov al, [ebx+edx-1] ; high byte of the shorter number cmp al, 0 ; negative? jb Add_Neg mov ax, 0 ; Extend with zeroes jmp short Add_Cont2 Add_Neg: mov ax, 0FFFFh ; Extend with ones Add_Cont2: push ax ; save sign extension for later CLC ; clear carry flag Add_Loop_1: mov al, [ebx] ; add one byte adc al, [esi] mov [edi], al Add_Check_O1: mov al, 0 ; 0 = no overflow jno Add_JNO1 mov al, 1 ; 1 = overflowed Add_JNO1: inc ebx ; increment pointers inc esi inc edi dec ecx ; decrement counts dec edx jnz Add_Loop_1 ; done with shorter number? jecxz Add_Loop_Done ; done with longer number? Add_Loop_2: mov al, [esp] ; get sign extension adc al, [esi] mov [edi], al Add_Check_O2: mov al, 0 ; 0 = no overflow jno Add_JNO2 mov al, 1 ; 1 = overflowed Add_JNO2: inc esi ; increment pointers inc edi dec ecx jnz Add_Loop_2 Add_Loop_Done: pop bx ; drop old sign extension jc Add_Carried ; No Carry cmp al, 1 jne Add_No_Overflow inc dword [esp] mov [edi], byte 0 ; sign extend zero jmp short Add_No_Overflow Add_Carried: cmp al, 1 jne Add_No_Overflow inc dword [esp] ; longer length + 1 mov [edi], byte 0FFh ; sign extend ones Add_No_Overflow: pop ecx ; length of result mov edi, [ebp+8] ; &sum mov [edi+4], ecx ; store length pop edi pop esi pop ebx leave ret