我一直在阅读div和mul组装操作,我决定通过在C中编写一个简单的程序来实现它们:
#include <stdlib.h>
#include <stdio.h>
int main()
{
    size_t i = 9;
    size_t j = i / 5;
    printf("%zu\n",j);
    return 0;
}
然后生成汇编语言代码:
gcc -S division.c -O0 -masm=intel
但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:
mov     rax, QWORD PTR [rbp-16]   ; Move i (=9) to RAX
movabs  rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul     rdx                       ; Multiply 9 by magic number
mov     rax, rdx                  ; Take only the upper 64 bits of the …Type类积分有两个操作quot和div,但在哈斯克尔2010语种报告它没有规定他们应该做的事情.假设这div是不可分割的,有什么quot不同,或者目的是quot什么?你什么时候使用一个,而另一个?
在我的计算机中,此代码需要17秒(1000万次):
static void Main(string[] args) {
   var sw = new Stopwatch(); sw.Start();
   int r;
   for (int i = 1; i <= 100000000; i++) {
      for (int j = 1; j <= 10; j++) {
         MyDivRem (i,j, out r);
      }
   }
   Console.WriteLine(sw.ElapsedMilliseconds);
}
static int MyDivRem(int dividend, int divisor, out int remainder) {
   int quotient = dividend / divisor;
   remainder = dividend - divisor * quotient;
   return quotient;
}
而Math.DivRem需要27秒.
.NET Reflector为我提供了Math.DivRem的代码:
public static int DivRem(int a, int b, out …可能重复:同时
划分和获取剩余?
是否可以在一个步骤中同时得到整数除法的商和余数,即不进行两次整数除法?
我试图弄清楚如何在汇编中计算模10,所以我在gcc中编译了以下c代码,看看它是什么产生的.
unsigned int i=999;
unsigned int j=i%10;
令我惊讶的是,我得到了
movl    -4(%ebp), %ecx
movl    $-858993459, %edx
movl    %ecx, %eax
mull    %edx
shrl    $3, %edx
movl    %edx, %eax
sall    $2, %eax
addl    %edx, %eax
addl    %eax, %eax
movl    %ecx, %edx
subl    %eax, %edx
movl    %edx, %eax
movl    %eax, -12(%ebp)
其中-4(%ebp)或"i"是输入,-12(%ebp)或"j"是答案.我已经测试了这个,无论你做出什么数字,它都能正常工作-4(%ebp).
我的问题是这个代码是如何工作的,它比使用div操作数更好.
如何同时执行除法和模数.处理器有可能吗?
喜欢 :
int a, b = 8 / 3; //a = 2, b = 2
或者是否有比以下更好的操作:
int a = 8 / 3;
int b = 8 % 3;
也许这更好?
int a = 8 / 3;
int b = 8 - a * 3;
谢谢.