【问题标题】:How to implement the mod operator in assembly如何在汇编中实现 mod 运算符
【发布时间】:2011-11-22 18:31:52
【问题描述】:

我正在学习汇编语言中的除法。根据我正在学习的书,idiv操作的结果放在eax中,其余的放在edx中。

书中的一个练习是在汇编中实现number = result % divisor

我原以为这相当于正常的除法运算,但结果是 edx。

但这不起作用,edx 似乎返回了垃圾。

为什么?上面的伪代码你是如何在汇编中实现的?

【问题讨论】:

  • 我会编写一个很小的 ​​C 函数,然后查看生成的程序集(例如使用 gcc -O -fverbose-asm -S tiny.c
  • 您的问题类似于stackoverflow.com/questions/8021772/… 如果您遇到特定问题,请显示您的实际代码(很可能您没有清除 rdx:rax、edx:eax 或 dx 的上半部分:斧头)。
  • 不看代码就很难猜到,但一个常见的失误是忘记在 idiv 之前将 edx 归零。

标签: assembly x86


【解决方案1】:

整数取模可以通过两种方式实现:

首先使用DIVIDIV,其中剩余部分将放入EDX,但您需要先将EDX归零,或者引用intel:

Operand Size -----------| Dividend | Divisor | Quotient | Remainder
Quadword/doubleword     | EDX:EAX  |  r/m32  |   EAX    |   EDX. 

例如:

eax = eax % 9

当无符号变为:

XOR EDX,EDX ;clear the destinations for outputs. this stops the garbage remainder  
MOV ECX,9
DIV ECX
MOV EAX,EDX

签名后是:

MOV ECX,9
CDQ ;this will clear EDX due to the sign extension
IDIV ECX
MOV EAX,EDX

第二种方法是在使用 2 的幂进行取模时使用的优​​化,在这种情况下,AND 比 2 的幂小一,例如:eax = eax % 8 变为 AND EAX,7

【讨论】:

  • 既然 idiv 是签名版本,你不应该 CDQ 到 edx 吗?
  • 我试图删除我的问题,但您已经回答了。我只想指出,在添加代码示例后它可能会发生一些变化。
  • @harold: 让我做有符号/无符号的例子,让事情变得更清楚
  • 到底是谁投了这个票,为什么?要么您不了解 x86 程序集,要么您因没有理由而拒绝投票......
  • @Necrolis 这不适用于签名号码。我得到负面结果。这不应该是正确的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-02
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
  • 2021-02-07
  • 1970-01-01
  • 2020-03-31
相关资源
最近更新 更多