Nhìn vào lắp ráp x86 do trình biên dịch tạo ra, tôi nhận thấy rằng các bộ phận số nguyên (chưa ký) đôi khi được thực hiện dưới dạng số nguyên. Những tối ưu hóa dường như theo các hình thứcThực hiện phép chia số nguyên sử dụng phép nhân
value/n => (value * ((0xFFFFFFFF/n) + 1))/0x100000000
Ví dụ, biểu diễn một bộ phận của 9:
12345678/9 = (12345678 * 0x1C71C71D)/0x100000000
Một bộ phận của 3 sẽ sử dụng phép nhân với 0x55555555 + 1
, và vân vân.
Khai thác thực tế là lệnh mul
lưu trữ phần cao của kết quả trong thanh ghi edx
, kết quả cuối cùng của bộ phận có thể thu được bằng cách sử dụng phép nhân đơn với giá trị phép thuật. (Mặc dù tối ưu hóa này đôi khi được sử dụng kết hợp với một chút thay đổi khôn ngoan ở cuối.)
Tôi muốn có một số thông tin chi tiết về cách thức này thực sự hoạt động. Cách tiếp cận này hợp lệ khi nào? Tại sao phải 1 được thêm vào "số ma thuật" của chúng tôi?
Hằng số mà bạn nhân với là xấp xỉ của nghịch đảo. Các ngẫu nhiên +/- 1 ở đây và có để đảm bảo rằng nó luôn luôn "làm tròn" một cách chính xác. Chứng minh rằng một phương pháp cụ thể là chính xác có thể được thực hiện bằng toán học, hoặc bằng cách kiểm tra sức mạnh vũ phu của tất cả các tử số. (Đối với 32-bit, điều này là hoàn toàn khả thi.) – Mysticial
@Mysticial: Điều đó trông giống như một câu trả lời cho tôi. –
@ScottHunter Có thể sau này khi tôi nghỉ việc. Tôi không có các công cụ ở đây để đưa ra một câu trả lời toàn diện. – Mysticial