Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 确定X86程序集中的内存访问时间_Assembly_X86 - Fatal编程技术网

Assembly 确定X86程序集中的内存访问时间

Assembly 确定X86程序集中的内存访问时间,assembly,x86,Assembly,X86,我试图确定访问两个内存地址的时间,这两个地址之间有一个特定的增量。我的代码必须混合使用x86和C,并将“裸机”运行(没有任何操作系统;编辑:我实际上是在修改memtest),以获得最精确的结果 我比x86更习惯于ARM组装,因此我可能犯了一些错误(我想知道,为什么mov在x86中做了这么多不同的事情)。我的代码如下 inline unsigned timeread (ulong addr, ulong delta, int iter) { ulong daddr; int i;

我试图确定访问两个内存地址的时间,这两个地址之间有一个特定的增量。我的代码必须混合使用x86和C,并将“裸机”运行(没有任何操作系统;编辑:我实际上是在修改memtest),以获得最精确的结果

我比x86更习惯于ARM组装,因此我可能犯了一些错误(我想知道,为什么mov在x86中做了这么多不同的事情)。我的代码如下

inline unsigned timeread (ulong addr, ulong delta, int iter)
{
    ulong daddr;
    int i;
    ulong st_low, st_high;
    ulong end_low, end_high;

    daddr = addr + delta;

    asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));

    for (i = 0; i < iter; ++i)
    {
        asm __volatile__ (
            "movl (%0), %%eax\n\t"
            :
            : "D" (addr)
            : "eax"
        );

        asm __volatile__ (
            "movl (%0), %%eax\n\t"
            :
            : "D" (daddr)
            : "eax"
        );
    }

    asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));

    asm __volatile__ (
        "subl %2,%0\n\t"
        "sbbl %3,%1"
        : "=a" (end_low), "=d" (end_high)
        : "g" (st_low), "g" (st_high),
            "0" (end_low), "1" (end_high)
    );

    return end_low;
}
inline unsigned timeread(ulong addr、ulong delta、int iter)
{
乌隆达德;
int i;
乌龙街低,街高;
ulong端低,端高;
daddr=addr+delta;
asm挥发性(“rdtsc”):“=a”(st_低)、“=d”(st_高));
对于(i=0;i
我正在使用gcc并使用标志-march=i486-m32进行编译


编辑:在调用该函数之前,我调用memtest提供的一个函数,set_cache(0),以便停用缓存(至少它是这么说的)。相反,调用set_cache(1)可以极大地减少执行时间(我从~2000个周期下降到抛开代码是否实际测量了您想要的值的问题不谈,您的代码是正确的。英特尔x86指令集不遵循ARM指令集设计时使用的相同原则。RISC有专门用于加载和存储到内存的单独指令。这与早期的CPU设计风格(追溯命名)不同,大多数指令都可以直接访问内存。不仅仅是移动指令,还可以执行添加和跳转等操作。因此,是的,您的MOVL指令在内存中加载32位值的EAX

请注意,由于您对两条MOVL asm语句都使用了
“D”
约束,编译器必须在每条asm语句之前重新加载EDI。由于没有明显的理由将其约束到EDI,我建议使用
“r”
约束,以便编译器可以选择两个不同的寄存器。启用优化后,编译器可以在循环外加载这两个寄存器一次,而不是在循环过程中每次加载一次。(如果不使用优化,则编译器将以任何一种方式加载寄存器,其中
addr
daddr
在每次循环迭代期间存储在堆栈上。)

例如:

    asm volatile (
        "movl (%0), %%eax\n\t"
        :
        : "r" (addr)
        : "eax"
    );

    asm volatile (
        "movl (%0), %%eax\n\t"
        :
        : "r" (daddr)
        : "eax"
    );

我不同意你的说法,这是C。在C中,整数和指针是不同的。这看起来不是很有用,实际上会发生的是两次内存访问,然后是大量缓存访问。你实际上没有问任何问题,但正如harold所说,这似乎没有衡量任何有用的东西。在上面执行这段代码也会很困难“裸机”作为GCC将生成32位代码。@EOF:代码基于memtest,我承认有些东西并不特别漂亮。@harold:在调用函数之前,缓存已被停用。