AMD x86 manual Example 8 Remainder

Models: x86

1 256
Download 256 pages 58.62 Kb
Page 105
Image 105

22007E/0 — November 1999

AMD Athlon™ Processor x86 Code Optimization

MOV

ECX, EAX

;save quotient

IMUL

EDI, EAX

;quotient * divisor hi-word

 

 

; (low only)

MUL

DWORD PTR [ESP+20];quotient * divisor lo-word

ADD

EDX, EDI

 

;EDX:EAX = quotient * divisor

SUB

EBX, EAX

 

;dividend_lo – (quot.*divisor)_lo

MOV

EAX, ECX

 

;get quotient

MOV

ECX, [ESP+16]

;dividend_hi

 

SBB

ECX, EDX

;subtract divisor *

quot. from dividend

SBB

EAX, 0

;adjust quotient if

remainder negative

XOR

EDX, EDX

;clear hi-word of quot(EAX<=FFFFFFFFh)

POP

EDI

;restore EDI as per

calling convention

POP

EBX

;restore EBX as per

calling convention

RET

 

;done, return to caller

_ulldiv ENDP

Example 8 (Remainder):

;_ullrem divides two unsigned 64-bit integers, and returns

;the remainder.

;INPUT: [ESP+8]:[ESP+4] dividend

;[ESP+16]:[ESP+12] divisor

;OUTPUT: EDX:EAX remainder of division

;

;DESTROYS: EAX,ECX,EDX,EFlags

_ullrem

PROC

 

PUSH

EBX

;save EBX as per calling convention

MOV

ECX, [ESP+20]

;divisor_hi

MOV

EBX, [ESP+16]

;divisor_lo

MOV

EDX, [ESP+12]

;dividend_hi

MOV

EAX, [ESP+8]

;dividend_lo

TEST

ECX, ECX

;divisor > 2^32–1?

JNZ

$r_big_divisor ;yes, divisor > 32^32–1

CMP

EDX, EBX

;only one division needed? (ECX = 0)

JAE

$r_two_divs

;need two divisions

DIV

EBX

;EAX = quotient_lo

MOV

EAX, EDX

;EAX = remainder_lo

MOV

EDX, ECX

;EDX = remainder_hi = 0

POP

EBX

;restore EBX as per calling convention

RET

 

;done, return to caller

Efficient 64-Bit Integer Arithmetic

89

Page 105
Image 105
AMD x86 manual Example 8 Remainder