/ / This Source Code Form is subject to the terms of the Mozilla Public / License, v. 2.0. If a copy of the MPL was not distributed with this / file, You can obtain one at http://mozilla.org/MPL/2.0/. .text / ebp - 36: caller's esi / ebp - 32: caller's edi / ebp - 28: / ebp - 24: / ebp - 20: / ebp - 16: / ebp - 12: / ebp - 8: / ebp - 4: / ebp + 0: caller's ebp / ebp + 4: return address / ebp + 8: a argument / ebp + 12: a_len argument / ebp + 16: b argument / ebp + 20: c argument / registers: / eax: / ebx: carry / ecx: a_len / edx: / esi: a ptr / edi: c ptr .globl s_mpv_mul_d .type s_mpv_mul_d,@function s_mpv_mul_d: push %ebp mov %esp,%ebp sub $28,%esp push %edi push %esi push %ebx movl $0,%ebx / carry = 0 mov 12(%ebp),%ecx / ecx = a_len mov 20(%ebp),%edi cmp $0,%ecx je L2 / jmp if a_len == 0 mov 8(%ebp),%esi / esi = a cld L1: lodsl / eax = [ds:esi]; esi += 4 mov 16(%ebp),%edx / edx = b mull %edx / edx:eax = Phi:Plo = a_i * b add %ebx,%eax / add carry (%ebx) to edx:eax adc $0,%edx mov %edx,%ebx / high half of product becomes next carry stosl / [es:edi] = ax; edi += 4; dec %ecx / --a_len jnz L1 / jmp if a_len != 0 L2: mov %ebx,0(%edi) / *c = carry pop %ebx pop %esi pop %edi leave ret nop / ebp - 36: caller's esi / ebp - 32: caller's edi / ebp - 28: / ebp - 24: / ebp - 20: / ebp - 16: / ebp - 12: / ebp - 8: / ebp - 4: / ebp + 0: caller's ebp / ebp + 4: return address / ebp + 8: a argument / ebp + 12: a_len argument / ebp + 16: b argument / ebp + 20: c argument / registers: / eax: / ebx: carry / ecx: a_len / edx: / esi: a ptr / edi: c ptr .globl s_mpv_mul_d_add .type s_mpv_mul_d_add,@function s_mpv_mul_d_add: push %ebp mov %esp,%ebp sub $28,%esp push %edi push %esi push %ebx movl $0,%ebx / carry = 0 mov 12(%ebp),%ecx / ecx = a_len mov 20(%ebp),%edi cmp $0,%ecx je L4 / jmp if a_len == 0 mov 8(%ebp),%esi / esi = a cld L3: lodsl / eax = [ds:esi]; esi += 4 mov 16(%ebp),%edx / edx = b mull %edx / edx:eax = Phi:Plo = a_i * b add %ebx,%eax / add carry (%ebx) to edx:eax adc $0,%edx mov 0(%edi),%ebx / add in current word from *c add %ebx,%eax adc $0,%edx mov %edx,%ebx / high half of product becomes next carry stosl / [es:edi] = ax; edi += 4; dec %ecx / --a_len jnz L3 / jmp if a_len != 0 L4: mov %ebx,0(%edi) / *c = carry pop %ebx pop %esi pop %edi leave ret nop / ebp - 36: caller's esi / ebp - 32: caller's edi / ebp - 28: / ebp - 24: / ebp - 20: / ebp - 16: / ebp - 12: / ebp - 8: / ebp - 4: / ebp + 0: caller's ebp / ebp + 4: return address / ebp + 8: a argument / ebp + 12: a_len argument / ebp + 16: b argument / ebp + 20: c argument / registers: / eax: / ebx: carry / ecx: a_len / edx: / esi: a ptr / edi: c ptr .globl s_mpv_mul_d_add_prop .type s_mpv_mul_d_add_prop,@function s_mpv_mul_d_add_prop: push %ebp mov %esp,%ebp sub $28,%esp push %edi push %esi push %ebx movl $0,%ebx / carry = 0 mov 12(%ebp),%ecx / ecx = a_len mov 20(%ebp),%edi cmp $0,%ecx je L6 / jmp if a_len == 0 cld mov 8(%ebp),%esi / esi = a L5: lodsl / eax = [ds:esi]; esi += 4 mov 16(%ebp),%edx / edx = b mull %edx / edx:eax = Phi:Plo = a_i * b add %ebx,%eax / add carry (%ebx) to edx:eax adc $0,%edx mov 0(%edi),%ebx / add in current word from *c add %ebx,%eax adc $0,%edx mov %edx,%ebx / high half of product becomes next carry stosl / [es:edi] = ax; edi += 4; dec %ecx / --a_len jnz L5 / jmp if a_len != 0 L6: cmp $0,%ebx / is carry zero? jz L8 mov 0(%edi),%eax / add in current word from *c add %ebx,%eax stosl / [es:edi] = ax; edi += 4; jnc L8 L7: mov 0(%edi),%eax / add in current word from *c adc $0,%eax stosl / [es:edi] = ax; edi += 4; jc L7 L8: pop %ebx pop %esi pop %edi leave ret nop / ebp - 20: caller's esi / ebp - 16: caller's edi / ebp - 12: / ebp - 8: carry / ebp - 4: a_len local / ebp + 0: caller's ebp / ebp + 4: return address / ebp + 8: pa argument / ebp + 12: a_len argument / ebp + 16: ps argument / ebp + 20: / registers: / eax: / ebx: carry / ecx: a_len / edx: / esi: a ptr / edi: c ptr .globl s_mpv_sqr_add_prop .type s_mpv_sqr_add_prop,@function s_mpv_sqr_add_prop: push %ebp mov %esp,%ebp sub $12,%esp push %edi push %esi push %ebx movl $0,%ebx / carry = 0 mov 12(%ebp),%ecx / a_len mov 16(%ebp),%edi / edi = ps cmp $0,%ecx je L11 / jump if a_len == 0 cld mov 8(%ebp),%esi / esi = pa L10: lodsl / %eax = [ds:si]; si += 4; mull %eax add %ebx,%eax / add "carry" adc $0,%edx mov 0(%edi),%ebx add %ebx,%eax / add low word from result mov 4(%edi),%ebx stosl / [es:di] = %eax; di += 4; adc %ebx,%edx / add high word from result movl $0,%ebx mov %edx,%eax adc $0,%ebx stosl / [es:di] = %eax; di += 4; dec %ecx / --a_len jnz L10 / jmp if a_len != 0 L11: cmp $0,%ebx / is carry zero? jz L14 mov 0(%edi),%eax / add in current word from *c add %ebx,%eax stosl / [es:edi] = ax; edi += 4; jnc L14 L12: mov 0(%edi),%eax / add in current word from *c adc $0,%eax stosl / [es:edi] = ax; edi += 4; jc L12 L14: pop %ebx pop %esi pop %edi leave ret nop / / Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized / so its high bit is 1. This code is from NSPR. / / mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, / mp_digit *qp, mp_digit *rp) / esp + 0: Caller's ebx / esp + 4: return address / esp + 8: Nhi argument / esp + 12: Nlo argument / esp + 16: divisor argument / esp + 20: qp argument / esp + 24: rp argument / registers: / eax: / ebx: carry / ecx: a_len / edx: / esi: a ptr / edi: c ptr / .globl s_mpv_div_2dx1d .type s_mpv_div_2dx1d,@function s_mpv_div_2dx1d: push %ebx mov 8(%esp),%edx mov 12(%esp),%eax mov 16(%esp),%ebx div %ebx mov 20(%esp),%ebx mov %eax,0(%ebx) mov 24(%esp),%ebx mov %edx,0(%ebx) xor %eax,%eax / return zero pop %ebx ret nop