Use backtick code blocks for syntax highlighting
This commit is contained in:
parent
8ed9dea394
commit
f658bfbb40
203 changed files with 26546 additions and 25801 deletions
154
09-06.md
154
09-06.md
|
|
@ -12,91 +12,95 @@ pages: 182-185
|
|||
|
||||
**LISTING 9.5 L9-5.ASM**
|
||||
|
||||
; Divides an arbitrarily long unsigned dividend by a 16-bit unsigned
|
||||
; divisor. C near-callable as:
|
||||
; unsigned int Div(unsigned int * Dividend,
|
||||
; int DividendLength, unsigned int Divisor,
|
||||
; unsigned int * Quotient);
|
||||
;
|
||||
; Returns the remainder of the division.
|
||||
;
|
||||
; Tested with TASM 2.
|
||||
```nasm
|
||||
; Divides an arbitrarily long unsigned dividend by a 16-bit unsigned
|
||||
; divisor. C near-callable as:
|
||||
; unsigned int Div(unsigned int * Dividend,
|
||||
; int DividendLength, unsigned int Divisor,
|
||||
; unsigned int * Quotient);
|
||||
;
|
||||
; Returns the remainder of the division.
|
||||
;
|
||||
; Tested with TASM 2.
|
||||
|
||||
parms struc
|
||||
dw 2 dup (?) ;pushed BP & return address
|
||||
Dividend dw ? ;pointer to value to divide, stored in Intel
|
||||
; order, with lsb at lowest address, msb at
|
||||
; highest. Must be composed of an integral
|
||||
; number of words
|
||||
DividendLength dw ? ;# of bytes in Dividend. Must be a multiple
|
||||
; of 2
|
||||
Divisor dw ? ;value by which to divide. Must not be zero,
|
||||
; or a Divide By Zero interrupt will occur
|
||||
Quotient dw ? ;pointer to buffer in which to store the
|
||||
; result of the division, in Intel order.
|
||||
; The quotient returned is of the same
|
||||
; length as the dividend
|
||||
parmsends
|
||||
parms struc
|
||||
dw 2 dup (?) ;pushed BP & return address
|
||||
Dividend dw ? ;pointer to value to divide, stored in Intel
|
||||
; order, with lsb at lowest address, msb at
|
||||
; highest. Must be composed of an integral
|
||||
; number of words
|
||||
DividendLength dw ? ;# of bytes in Dividend. Must be a multiple
|
||||
; of 2
|
||||
Divisor dw ? ;value by which to divide. Must not be zero,
|
||||
; or a Divide By Zero interrupt will occur
|
||||
Quotient dw ? ;pointer to buffer in which to store the
|
||||
; result of the division, in Intel order.
|
||||
; The quotient returned is of the same
|
||||
; length as the dividend
|
||||
parmsends
|
||||
|
||||
.model small
|
||||
.code
|
||||
public _Div
|
||||
_Divprocnear
|
||||
push bp ;preserve caller's stack frame
|
||||
mov bp,sp ;point to our stack frame
|
||||
push si ;preserve caller's register variables
|
||||
push di
|
||||
.model small
|
||||
.code
|
||||
public _Div
|
||||
_Divprocnear
|
||||
push bp ;preserve caller's stack frame
|
||||
mov bp,sp ;point to our stack frame
|
||||
push si ;preserve caller's register variables
|
||||
push di
|
||||
|
||||
std ;we're working from msb to lsb
|
||||
mov ax,ds
|
||||
mov es,ax ;for STOS
|
||||
mov cx,[bp+DividendLength]
|
||||
sub cx,2
|
||||
mov si,[bp+Dividend]
|
||||
add si,cx ;point to the last word of the dividend
|
||||
; (the most significant word)
|
||||
mov di,[bp+Quotient]
|
||||
add di,cx ;point to the last word of the quotient
|
||||
; buffer (the most significant word)
|
||||
mov bx,[bp+Divisor]
|
||||
shr cx,1
|
||||
inc cx ;# of words to process
|
||||
sub dx,dx ;convert initial divisor word to a 32-bit
|
||||
;value for DIV
|
||||
DivLoop:
|
||||
lod sw ;get next most significant word of divisor
|
||||
div bx
|
||||
sto sw ;save this word of the quotient
|
||||
;DX contains the remainder at this point,
|
||||
; ready to prepend to the next divisor word
|
||||
loop DivLoop
|
||||
mov ax,dx ;return the remainder
|
||||
cld ;restore default Direction flag setting
|
||||
pop di ;restore caller's register variables
|
||||
pop si
|
||||
pop bp ;restore caller's stack frame
|
||||
ret
|
||||
_Divendp
|
||||
end
|
||||
std ;we're working from msb to lsb
|
||||
mov ax,ds
|
||||
mov es,ax ;for STOS
|
||||
mov cx,[bp+DividendLength]
|
||||
sub cx,2
|
||||
mov si,[bp+Dividend]
|
||||
add si,cx ;point to the last word of the dividend
|
||||
; (the most significant word)
|
||||
mov di,[bp+Quotient]
|
||||
add di,cx ;point to the last word of the quotient
|
||||
; buffer (the most significant word)
|
||||
mov bx,[bp+Divisor]
|
||||
shr cx,1
|
||||
inc cx ;# of words to process
|
||||
sub dx,dx ;convert initial divisor word to a 32-bit
|
||||
;value for DIV
|
||||
DivLoop:
|
||||
lod sw ;get next most significant word of divisor
|
||||
div bx
|
||||
sto sw ;save this word of the quotient
|
||||
;DX contains the remainder at this point,
|
||||
; ready to prepend to the next divisor word
|
||||
loop DivLoop
|
||||
mov ax,dx ;return the remainder
|
||||
cld ;restore default Direction flag setting
|
||||
pop di ;restore caller's register variables
|
||||
pop si
|
||||
pop bp ;restore caller's stack frame
|
||||
ret
|
||||
_Divendp
|
||||
end
|
||||
```
|
||||
|
||||
**LISTING 9.6 L9-6.C**
|
||||
|
||||
/* Sample use of Div function to perform division when the result
|
||||
doesn't fit in 16 bits */
|
||||
```c
|
||||
/* Sample use of Div function to perform division when the result
|
||||
doesn't fit in 16 bits */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern unsigned int Div(unsigned int * Dividend,
|
||||
int DividendLength, unsigned int Divisor,
|
||||
unsigned int * Quotient);
|
||||
extern unsigned int Div(unsigned int * Dividend,
|
||||
int DividendLength, unsigned int Divisor,
|
||||
unsigned int * Quotient);
|
||||
|
||||
main() {
|
||||
unsigned long m, i = 0x20000001;
|
||||
unsigned int k, j = 0x10;
|
||||
main() {
|
||||
unsigned long m, i = 0x20000001;
|
||||
unsigned int k, j = 0x10;
|
||||
|
||||
k = Div((unsigned int *)&i, sizeof(i), j, (unsigned int *)&m);
|
||||
printf("%lu / %u = %lu r %u\n", i, j, m, k);
|
||||
}
|
||||
k = Div((unsigned int *)&i, sizeof(i), j, (unsigned int *)&m);
|
||||
printf("%lu / %u = %lu r %u\n", i, j, m, k);
|
||||
}
|
||||
```
|
||||
|
||||
#### Sweet Spot Revisited {#Heading9}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue