tôi đã viết các chức năng sau cho ARM GNU
lắp ráp. Nếu bạn không có CPU có hỗ trợ máy udiv/sdiv
, chỉ cần cắt một vài dòng đầu tiên lên nhãn "0:" trong một trong hai chức năng.
.arm
.cpu cortex-a7
.syntax unified
.type udiv,%function
.globl udiv
udiv: tst r1,r1
bne 0f
udiv r3,r0,r2
mls r1,r2,r3,r0
mov r0,r3
bx lr
0: cmp r1,r2
movhs r1,r2
bxhs lr
mvn r3,0
1: adds r0,r0
adcs r1,r1
cmpcc r1,r2
subcs r1,r2
orrcs r0,1
lsls r3,1
bne 1b
bx lr
.size udiv,.-udiv
.type sdiv,%function
.globl sdiv
sdiv: teq r1,r0,ASR 31
bne 0f
sdiv r3,r0,r2
mls r1,r2,r3,r0
mov r0,r3
bx lr
0: mov r3,2
adds r0,r0
and r3,r3,r1,LSR 30
adcs r1,r1
orr r3,r3,r2,LSR 31
movvs r1,r2
ldrvc pc,[pc,r3,LSL 2]
bx lr
.int 1f
.int 3f
.int 5f
.int 11f
1: cmp r1,r2
movge r1,r2
bxge lr
mvn r3,1
2: adds r0,r0
adcs r1,r1
cmpvc r1,r2
subge r1,r2
orrge r0,1
lsls r3,1
bne 2b
bx lr
3: cmn r1,r2
movge r1,r2
bxge lr
mvn r3,1
4: adds r0,r0
adcs r1,r1
cmnvc r1,r2
addge r1,r2
orrge r0,1
lsls r3,1
bne 4b
rsb r0,0
bx lr
5: cmn r1,r2
blt 6f
tsteq r0,r0
bne 7f
6: mov r1,r2
bx lr
7: mvn r3,1
8: adds r0,r0
adcs r1,r1
cmnvc r1,r2
blt 9f
tsteq r0,r3
bne 10f
9: add r1,r2
orr r0,1
10: lsls r3,1
bne 8b
rsb r0,0
bx lr
11: cmp r1,r2
blt 12f
tsteq r0,r0
bne 13f
12: mov r1,r2
bx lr
13: mvn r3,1
14: adds r0,r0
adcs r1,r1
cmpvc r1,r2
blt 15f
tsteq r0,r3
bne 16f
15: sub r1,r2
orr r0,1
16: lsls r3,1
bne 14b
bx lr
Có hai hàm, udiv
cho phân chia số nguyên không dấu và sdiv
cho phân chia số nguyên đã ký. Cả hai đều mong đợi một cổ tức 64 bit (đã ký hoặc chưa ký) trong r1
(từ cao) và r0
(từ thấp) và một số chia 32 bit trong r2
. Chúng trả về thương số trong r0
và số còn lại trong r1
, do đó bạn có thể xác định chúng trong một số C header
là extern
trả lại số nguyên 64 bit và che dấu thương và số dư sau đó. Lỗi (phân chia bởi 0 hoặc tràn) được biểu thị bằng phần còn lại có giá trị tuyệt đối lớn hơn hoặc bằng giá trị tuyệt đối của số chia. Thuật toán phân chia đã ký sử dụng phân biệt chữ hoa với các dấu hiệu của cả cổ tức và số chia; nó không chuyển đổi sang số nguyên dương đầu tiên, vì điều đó sẽ không phát hiện tất cả các điều kiện tràn đúng cách.
Tất nhiên trình biên dịch sẽ hỗ trợ phân chia số nguyên trong chế độ phần mềm ngay cả khi không có trong phần cứng. Tôi nghi ngờ những chip spec cao không có phân chia số nguyên. Tôi nghĩ rằng ATMega (như Arduino) thiếu nó. – leppie
Lệnh ghép nối để phân chia số nguyên trên ARM không tồn tại. – Phonon
Hoặc chuyển đổi sang phao hoặc thực hiện phân chia thủ công với mẫu mã opcode 3 chưa được kiểm soát. –