NASM:大数除以小数

发布于 2024-11-06 12:41:17 字数 829 浏览 1 评论 0原文

NASM手册关于DIV说:

  • 对于DIV r/m32,EDX:EAX除以给定的操作数;商存储在 EAX 中,余数存储在 EDX 中。

如果 EDX:EAX 是 259 左右的大数并且除法器是 3 该怎么办?商显然无法放入 EAX 中。假设我不关心其余的。我想要进行划分的最佳实践。

考虑分步骤划分高 32 位和低 32 位。我想我可以找出一些丑陋的结果,但我会对好的结果感兴趣。快速检查 EAX 可能保留商的情况,从而避免复杂的魔术。

解决方案:drhirsch的答案转换为NASM语法:

; this divides edx:eax by ebx, even if the result is bigger than 2^32.
; result is in edx:eax, ecx,esi are used as spare registers
mov ecx, eax           ;save lower 32 bit
mov eax, edx
xor edx, edx           ;now edx:eax contains 0:hi32 
div ebx
mov esi, eax           ;hi 32 bit of result, save to esi
mov eax, ecx           ;now edx:eax contains r:lo32, where r is the remainder
div ebx
mov edx, esi           ;restore hi32

NASM manual says on DIV:

  • For DIV r/m32, EDX:EAX is divided by the given operand; the quotient is stored in EAX and the remainder in EDX.

What if EDX:EAX is a large number around 259 and the divider is 3? The quotient clearly cannot fit into EAX. Let's say I do not care about the remainder. I would like to have a best practice for doing the division.

Thinking about dividing the upper and lower 32 bits in separate steps. I think I could figure out some ugly result, but I would be interested in a good one. With a quick check for the case when EAX is likely to hold the quotient thus avoiding the complicated magic.

Solution: drhirsch's answer converted to NASM syntax:

; this divides edx:eax by ebx, even if the result is bigger than 2^32.
; result is in edx:eax, ecx,esi are used as spare registers
mov ecx, eax           ;save lower 32 bit
mov eax, edx
xor edx, edx           ;now edx:eax contains 0:hi32 
div ebx
mov esi, eax           ;hi 32 bit of result, save to esi
mov eax, ecx           ;now edx:eax contains r:lo32, where r is the remainder
div ebx
mov edx, esi           ;restore hi32

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡莣 2024-11-13 12:41:17

该代码未经测试。它应该计算 (d*2^32 + a)/b:

;this divides edx:eax by ebx, even if the result is bigger than 2^32.
;result is in edx:eax, ecx,esi are used as spare registers
;AT&T syntax.
  mov %eax, %ecx           ;save lower 32 bit
  mov %edx, %eax
  xor %edx, %edx           ;now edx:eax contains 0:hi32 
  div %ebx
  mov %eax, %esi           ;hi 32 bit of result
  mov %ecx, %eax           ;now edx:eax contains r:lo32, where r is the remainder
  div %ebx
  mov %esi, %edx           ;restore hi32                 

This code is untested. It should calculate (d*2^32 + a)/b:

;this divides edx:eax by ebx, even if the result is bigger than 2^32.
;result is in edx:eax, ecx,esi are used as spare registers
;AT&T syntax.
  mov %eax, %ecx           ;save lower 32 bit
  mov %edx, %eax
  xor %edx, %edx           ;now edx:eax contains 0:hi32 
  div %ebx
  mov %eax, %esi           ;hi 32 bit of result
  mov %ecx, %eax           ;now edx:eax contains r:lo32, where r is the remainder
  div %ebx
  mov %esi, %edx           ;restore hi32                 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文