使用单个 divl 指令进行除法和模数(i386、amd64)
我试图为 gcc 提供内联汇编,以使用单个 divl
指令获得除法和模数。不幸的是,我不太擅长组装。有人可以帮我解决这个问题吗?谢谢。
I was trying to come up with inline assembly for gcc to get both division and modulus using single divl
instruction. Unfortunately, I am not that good at assembly. Could someone please help me on this? Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你正在寻找这样的东西:
虽然我同意其他评论者的观点,通常 GCC 会为你做这件事,并且你应该尽可能避免内联汇编,但有时你需要这种构造。
例如,如果高位字小于模数,则可以安全地执行这样的除法。然而,GCC 还不够聪明,无法意识到这一点,因为在一般情况下,将 64 位数字除以 32 位数字可能会导致溢出,因此它会调用库例程来完成额外的工作。 (对于 64 位 ISA,替换为 128 位/64 位。)
You're looking for something like this:
Although I agree with the other commenters that usually GCC will do this for you and you should avoid inline assembly when possible, sometimes you need this construct.
For instance, if the high word is less than the modulus, then it is safe to perform the division like this. However, GCC isn't smart enough to realize this, because in the general case dividing a 64 bit number by a 32 bit number can lead to overflow, and so it calls to a library routine to do extra work. (Replace with 128 bit/64 bit for 64 bit ISAs.)
您不应该尝试自己优化它。 GCC 已经这样做了。
运行
产生结果
请注意,余数 %edx 没有移动,因为它也是传递给 printf 的第三个参数。
编辑:32 位版本不太混乱。传递 -m32 产量
You shouldn't try to optimize this yourself. GCC already does this.
Running
yields
Notice that the remainder, %edx, is not moved because it is also the third argument passed to printf.
EDIT: The 32-bit version is less confusing. Passing -m32 yields
幸运的是,您不必借助内联汇编来实现此目的。 gcc 会在可能的情况下自动执行此操作。
$ cat divmod.c
$ gcc -O3 -std=c99 -Wall -Wextra -pedantic -S divmod.c -o -
Fortunately, you don't have to resort to inline assembly to achieve this. gcc will do this automatically when it can.
$ cat divmod.c
$ gcc -O3 -std=c99 -Wall -Wextra -pedantic -S divmod.c -o -
是的——divl 将在 eax 中产生商,在 edx 中产生余数。使用 Intel 语法,例如:
Yes -- a divl will produce the quotient in eax and the remainder in edx. Using Intel syntax, for example:
这是Linux内核代码中关于divl的示例
Here is an example in linux kernel code about divl