0

嘿,我知道我一直在问很多问题.. 但在谷歌上没有太多资源,所以希望这将有助于未来尝试做类似项目的人,我也总是谷歌解决方案,但我从来没有搜索过第一页。

我看了亚历克斯发布的英特尔手册,对我来说似乎很陌生 http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer- vol-2a-2b-instruction-set-az-manual.html

所以我想我知道一个简单的DIV操作码是如何工作的。因为它divide毕竟是。我毫不费力地添加ADD, SUB,当然IMUL有问题你们帮我解决了那个问题。似乎在难度方面DIV属于同一类别IMUL

好吧,不用手册就用 OllyDbg 做自我调试测试。

我发现除法的答案总是存储在EAX. 想通了,剩下的也留着谁知道,存放在EDX.

研究这个算法非常重要,谁知道,有人会使用随机数除法的余数来生成从 0 到 10 的切换非常聪明。但我的问题仍然存在。

这已经很奇怪了,我从没想过被除的十六进制数会有余数,小数点甚至都不属于它们。

DIV ECX

就像

regs.d.eax /= regs.d.ecx;
regs.d.edx = regs.d.eax % regs.d.ecx;

我在想也许先得到余数……只是简单的事情。

regs.d.edx = regs.d.eax % regs.d.ecx;
regs.d.eax /= regs.d.ecx;

好吧,我几乎不使用数学编程,所以对我来说有点困惑。我更像是一个将结果存储在一个字符串中然后用小数点分割的人,这就是我得到剩余部分的方式是的,我知道它很慢而且它采取了简单的方法......而且我自己反对使用字符串数学代码中的运算。

好吧..看看我放在那里的那个C代码..可能必须在临时变量中发生除法之前存储两者..EAX或者ECX首先执行剩余代码..然后是除法代码。我不知道。

好吧,我会看到,也许你们可以为我提供更好的答案,也许它不能在一行中完成,但也许我犯了一些错误.. 由于许多其他事情,我无法真正测试我现在所做的事情在我编译软件之前必须修复。

4

2 回答 2

2

这些手册并不容易阅读,这是真的,但它们为您的问题提供了所有答案(嗯,其中大多数,文档中偶尔会有遗漏和错误)。

您在猜测的算法中缺少的一件事是 DIV 通常将 2N 位除以 N 位,也就是说,当您DIV ECX将 EDX:EAX 中包含的 64 位无符号值除以 ECX 中的 32 位无符号值时。然后将商存储在 EAX 中,将余数存储在 EDX 中。

您还应该记住除法溢出的可能性(在这种情况下,EDX>=ECX 是它的条件)以及指令在 EFLAGS 寄存器中修改的标志。

于 2011-10-14T10:25:02.477 回答
0

我认为一个相当公平的翻译是:

  int16_t a=42,b=7;
  int16_t div = a/7;
  int16_t remainder = a - (div*b);

在实践中,这可能或可能不等同于remainder = a % b(我需要查找标准规范)。如果您仔细考虑负数会发生什么,它会变得更有趣。

尽管如此,小数点永远不会发挥作用,所以我不明白你为什么在帖子中提到它。

也许它不能在一行中完成[...]

我高度怀疑编译器会重新使用子表达式,并在适用时自动使用 (E)DX 的剩余部分。(这对于编译器来说是相当微不足道的优化)

于 2011-10-14T10:18:34.820 回答