📄 divide.s
字号:
CMP ip, a3, ASL #1
BLS u_shifted1mod8
CMP ip, a3, ASL #2
BLS u_shifted2mod8
CMP ip, a3, ASL #3
BLS u_shifted3mod8
CMP ip, a3, ASL #4
BLS u_shifted4mod8
CMP ip, a3, ASL #5
BLS u_shifted5mod8
CMP ip, a3, ASL #6
BLS u_shifted6mod8
CMP ip, a3, ASL #7
MOVHI a3, a3, ASL #8
BHI u_loop
u_loop2
u_shifted7mod8
CMP a2, a3, ASL #7
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #7
u_shifted6mod8
CMP a2, a3, ASL #6
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #6
u_shifted5mod8
CMP a2, a3, ASL #5
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #5
u_shifted4mod8
CMP a2, a3, ASL #4
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #4
u_shifted3mod8
CMP a2, a3, ASL #3
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #3
u_shifted2mod8
CMP a2, a3, ASL #2
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #2
u_shifted1mod8
CMP a2, a3, ASL #1
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #1
u_shifted0mod8
CMP a2, a3, ASL #0
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #0
CMP a1, a3, LSR #1
MOVLS a3, a3, LSR #8
BLS u_loop2
MOV a1, a4
RET
|__rt_udiv10| ; udiv10 ;
;
; Fast unsigned divide by 10: dividend in a1, divisor in a2.
; Returns quotient in a1, remainder in a2.
; Also destroys a3.
;
; Calculate x / 10 as (x * 2**32/10) / 2**32.
; That is, we calculate the most significant word of the double-length
; product. In fact, we calculate an approximation which may be 1 off
; because we've ignored a carry from the least significant word we didn't
; calculate. We correct for this by insisting that the remainder < 10
; and by incrementing the quotient if it isn't.
MOV a2, a1
MOV a1, a1, LSR #1
ADD a1, a1, a1, LSR #1
ADD a1, a1, a1, LSR #4
ADD a1, a1, a1, LSR #8
ADD a1, a1, a1, LSR #16
MOV a1, a1, LSR #3
ADD a3, a1, a1, ASL #2
SUB a2, a2, a3, ASL #1
CMP a2, #10
ADDGE a1, a1, #1
SUBGE a2, a2, #10
RET
|__rt_sdiv| ; sdiv ;
;
; Signed divide of a2 by a1: returns quotient in a1, remainder in a2
; Quotient is truncated (rounded towards zero).
; Sign of remainder = sign of dividend.
; Also destroys a3, a4 and ip.
; Makes dividend and divisor non-negative, then does an unsigned divide;
; the proper signs get sorted out again at the end.
; The code is mostly as for udiv, except that the justification part is
; slightly simplified by knowledge that the dividend is in the range
; [0..#x80000000]. One register may be gained thereby.
MOVS ip, a1
BEQ dividebyzero
RSBMI a1, a1, #0 ; absolute value of divisor
EOR ip, ip, a2
ANDS a4, a2, #&80000000
ORR ip, a4, ip, LSR #1
; ip bit 31 sign of dividend (= sign of remainder)
; bit 30 sign of dividend EOR sign of divisor (= sign of quotient)
RSBNE a2, a2, #0 ; absolute value of dividend
MOV a3, a1
MOV a4, #0
s_loop
CMP a2, a3, ASL #0
BLS s_shifted0mod8
CMP a2, a3, ASL #1
BLS s_shifted1mod8
CMP a2, a3, ASL #2
BLS s_shifted2mod8
CMP a2, a3, ASL #3
BLS s_shifted3mod8
CMP a2, a3, ASL #4
BLS s_shifted4mod8
CMP a2, a3, ASL #5
BLS s_shifted5mod8
CMP a2, a3, ASL #6
BLS s_shifted6mod8
CMP a2, a3, ASL #7
MOVHI a3, a3, ASL #8
BHI s_loop
s_loop2
CMP a2, a3, ASL #7
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #7
CMP a2, a3, ASL #6
s_shifted6mod8
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #6
CMP a2, a3, ASL #5
s_shifted5mod8
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #5
CMP a2, a3, ASL #4
s_shifted4mod8
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #4
CMP a2, a3, ASL #3
s_shifted3mod8
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #3
CMP a2, a3, ASL #2
s_shifted2mod8
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #2
CMP a2, a3, ASL #1
s_shifted1mod8
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #1
CMP a2, a3, ASL #0
s_shifted0mod8
ADC a4, a4, a4
SUBHS a2, a2, a3, ASL #0
CMP a1, a3, LSR #1
MOVLS a3, a3, LSR #8
BLS s_loop2
MOV a1, a4
TST ip, #&40000000
RSBNE a1, a1, #0
TST ip, #&80000000
RSBNE a2, a2, #0
RET
|__rt_sdiv10| ; sdiv10 ;
;
; Fast signed divide by 10: dividend in a1, divisor in a2.
; Returns quotient in a1, remainder in a2.
; Also destroys a3 and a4.
; Quotient is truncated (rounded towards zero).
MOVS a4, a1
RSBMI a1, a1, #0
MOV a2, a1
MOV a1, a1, LSR #1
ADD a1, a1, a1, LSR #1
ADD a1, a1, a1, LSR #4
ADD a1, a1, a1, LSR #8
ADD a1, a1, a1, LSR #16
MOV a1, a1, LSR #3
ADD a3, a1, a1, ASL #2
SUB a2, a2, a3, ASL #1
CMP a2, #10
ADDGE a1, a1, #1
SUBGE a2, a2, #10
CMP a4, #0
RSBMI a1, a1, #0
RSBMI a2, a2, #0
RET
|__rt_divtest| ; divtest ;
;
; Test for division by zero (used when division is voided).
CMPS a1, #0
RET NE
B dividebyzero
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -