【问题标题】:How can I check if a register is evenly divisible by 7?如何检查寄存器是否能被 7 整除?
【发布时间】:2016-10-15 18:23:47
【问题描述】:

我想检查寄存器 ax 的值是否能被 7 整除,余数 = 0。我该怎么做?

【问题讨论】:

  • 应该将AX中的值视为有符号还是无符号?您是否仅限于 16 位模式,如果是,为什么?使用 IDIV 的答案是否可以接受,或者您是否正在寻找避免(慢)硬件除法指令的巧妙技巧?为什么你首先要手动编写汇编语言?

标签: math assembly x86 division


【解决方案1】:

您可以使用与this answer 相同的方式,当然可以使用不同的常量。

7 mod 216 的模乘逆是 0x6db7,这(根据定义)意味着 x = n * 7 形式的数字将服从 x * 0x6db7 = n,其中 n 将小于或等于0xffff / 7。所以如果你从x * 0x6db7 中得到更大的东西,你知道它不是 7 的倍数。此外,非 7 的倍数也不能映射到低结果,因为乘以奇数模 2 的幂是双射的。

所以你可以使用(未​​测试)

imul ax, ax, 0x6db7
cmp ax, 0x2492
ja not_multiple_of_7

这当然适用于无符号数。

作为奖励,ax 将是原始值除以 7 它是 7 的倍数。

【讨论】:

  • 如果你有一个带乘法的 CPU(例如,你展示的 Intel),通常还有一个除法指令会产生一个余数;除并检查余数。这在概念上更简单。当此检查的性能很重要时,您的方案是好的;如果是这样,那么应该使用这个方案(并用适当的 cmets 标记)在大多数情况下,性能并不重要,而且这种魔法对大多数读者来说是不透明的,产生的代码难以维护,因为它依赖于数学大多数读者没有。 (赞成,因为它很聪明)。
  • @IraBaxter:我认为问题中的“没有余数”短语的意思是“没有 using 余数指令”。但 OP 的自我回答证明这不是本意。
【解决方案2】:
  org 100h   
  mov ax,14
  mov cl,7
  div cl
  cmp ah,0
  je positive
  PRINTN "The number has a remainder"
  jmp finish
 positive:
  PRINTN "The number has no remainder"
 finish:
 PRINTN "After comparison"
mov ah, 0
int 16h
ret

【讨论】:

  • 好的,但要小心,它依赖于 255 或以下的商,1792 及以上将导致#DE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 2018-01-14
相关资源
最近更新 更多