As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center作为指导。
                            
                        
                    
                
                                7年前关闭。
            
                    
谢谢大家对我的耐心。我只需要把头缠在我正在看的东西上。抱歉,请尝试学习和理解。

重新阅读了每个人的注释并浏览了几次代码后,我意识到我的问题针对了错误的方向。一世

我可以用简单的组装说明替换这两行吗?还是我必须做类似asm()的事情。我想这就是我的困惑。一旦我知道了这一点,我想我会从那里开始的。

编辑

我没有意识到我从帖子中忽略了这一点。显然,最重要的部分是Oli,感谢您指出这一点。

目标是用内联汇编代码替换附加程序中for循环内的两行代码。您必须从内联汇编代码中获得相同的输出。 (执行相同的结果,循环数相同)

C :

#include "stdlib.h"
#include "time.h"

int main (int argc, char* argv[])
{
    int num1 = 10;
    int num2 = 27;
    int sum = 0;
    int cases = 0;
    int loose = 0;
    float time1 = 0;
    float time2 = 0;
    float time = 0;
    int i = 0;

    sum = num1 + num2;

    asm("xor %%eax,%%eax;"
        "mov %1,%%eax;"
        "add %2,%%eax;"
        "mov %%eax,%0;"
        :"=r"(sum)                   /* outputs */
        :"r"(num1),"r"(num2)         /* input   */
        :"%eax");                    /*clobber list*/

    printf("The sum is %d \n",sum);

    time1 = clock();
    for (i = 0; i<1000000000; i++)
    {

        cases = i/num1;
        loose = i%num1;

    }
    printf("The number of cases are %d \n",cases);
    printf("The number of loose items are %d \n",loose);

    time2 = clock();

    time = (time2 - time1) / CLOCKS_PER_SEC;

    printf("The elapsed time is %f seconds \n", time);

    system("pause");
    return 0;
}




部件 :

.file   "inlineAsm.c"
.def    ___main;    .scl    2;  .type   32; .endef
.section .rdata,"dr"

LC1:
    .ascii "The sum is %d \12\0"
LC2:
    .ascii "The number of cases are %d \12\0"
    .align 4
LC3:
    .ascii "The number of loose items are %d \12\0"
    .align 4
LC5:
    .ascii "The elapsed time is %f seconds \12\0"
LC6:
    .ascii "pause\0"
    .align 4
LC4:
    .long   1148846080
    .text
.globl _main
    .def    _main;  .scl    2;  .type   32; .endef

_main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $56, %esp
    andl    $-16, %esp
    movl    $0, %eax
    addl    $15, %eax
    addl    $15, %eax
    shrl    $4, %eax
    sall    $4, %eax
    movl    %eax, -40(%ebp)
    movl    -40(%ebp), %eax
    call    __alloca
    call    ___main
    movl    $10, -4(%ebp)
    movl    $27, -8(%ebp)
    movl    $0, -12(%ebp)
    movl    $0, -16(%ebp)
    movl    $0, -20(%ebp)
    movl    $0x00000000, %eax
    movl    %eax, -24(%ebp)
    movl    $0x00000000, %eax
    movl    %eax, -28(%ebp)
    movl    $0x00000000, %eax
    movl    %eax, -32(%ebp)
    movl    $0, -36(%ebp)
    movl    -8(%ebp), %eax
    addl    -4(%ebp), %eax
    movl    %eax, -12(%ebp)
    movl    -4(%ebp), %ecx
    movl    -8(%ebp), %edx
/APP
    xor %eax,%eax;mov %ecx,%eax;add %edx,%eax;mov %eax,%edx;
/NO_APP
    movl    %edx, %eax
    movl    %eax, -12(%ebp)
    movl    -12(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    $LC1, (%esp)
    call    _printf
    call    _clock
    pushl   %eax
    fildl   (%esp)
    leal    4(%esp), %esp
    fstps   -24(%ebp)
    movl    $0, -36(%ebp)
L2:
    cmpl    $999999999, -36(%ebp)
    jg  L3
    movl    -36(%ebp), %edx
    leal    -4(%ebp), %ecx
    movl    %ecx, -40(%ebp)
    movl    %edx, %eax
    movl    -40(%ebp), %ecx
    cltd
    idivl   (%ecx)
    movl    %eax, -40(%ebp)
    movl    -40(%ebp), %eax
    movl    %eax, -16(%ebp)
    movl    -36(%ebp), %edx
    leal    -4(%ebp), %ecx
    movl    %ecx, -40(%ebp)
    movl    %edx, %eax
    movl    -40(%ebp), %ecx
    cltd
    idivl   (%ecx)
    movl    %edx, -20(%ebp)
    leal    -36(%ebp), %eax
    incl    (%eax)
    jmp L2
L3:
    movl    -16(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    $LC2, (%esp)
    call    _printf
    movl    -20(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    $LC3, (%esp)
    call    _printf
    call    _clock
    pushl   %eax
    fildl   (%esp)
    leal    4(%esp), %esp
    fstps   -28(%ebp)
    flds    -28(%ebp)
    fsubs   -24(%ebp)
    flds    LC4
    fdivrp  %st, %st(1)
    fstps   -32(%ebp)
    flds    -32(%ebp)
    fstpl   4(%esp)
    movl    $LC5, (%esp)
    call    _printf
    movl    $LC6, (%esp)
    call    _system
    movl    $0, %eax
    leave
    ret
    .def    _system     ;.scl   3;  .type   32; .endef
    .def    _clock      ;.scl   3;  .type   32; .endef
    .def    _printf     ;.scl   3;  .type   32; .endef




输出:

/*
The sum is 37
The number of cases are 99999999
The number of loose items are 9
The elapsed time is 9.359000 seconds
Press any key to continue . . .
*/

最佳答案

根据您在最近编辑中添加的信息,您需要在循环内修改代码以使程序更快。

在我看来,程序缓慢的原因是因为它无缘无故地循环了1000000000次。

显然,最好的办法是完全消除环路。但是,如果您仅限于修改循环内的代码,那么也许可以让循环在除最后一次迭代之外的每次迭代中执行NOOP吗?

注意:这是一个非常奇怪的问题,我仍然认为对分配参数可能存在一些误解。

编辑:让我们看一下内联程序集:

asm("xor %%eax,%%eax;"
    "mov %1,%%eax;"
    "add %2,%%eax;"
    "mov %%eax,%0;"
    :"=r"(sum)                   /* outputs */
    :"r"(num1),"r"(num2)         /* input   */
    :"%eax");                    /*clobber list*/


出于优化目的,您需要了解的最重要的事情是它只能运行一次。不仅如此,它还执行着非常简单和快速的操作,如果使用C编写它也可能同样简单和快速。拥有这种内联汇编除了使程序更复杂之外没有意义,这是我的另一个原因认为这项任务有些奇怪。似乎到处都是红鲱鱼。

让我们逐行看一下汇编器。

第一行是将%eax寄存器清零的简便方法。如果您xor本身带有某些内容,则结果始终为零。 (我不知道为什么需要在这里,因为您将在下一行覆盖%eax的内容。)

第二行将变量1装入%eax,这是第一个输入(num1)。

第三行将变量2(num2)添加到%eax

第四行将结果复制到输出变量(%eax)中,该结果已装入sum

其余各行按顺序(0,1,2)定义了我们刚才引用的变量,并且还告诉编译器您刚刚使用了%eax寄存器,因此在下一次使用它之前必须将其清除。

您只需在C语言中简单地添加即可轻松替换所有该汇编程序,而且速度不会降低。编译器非常聪明。

基本上,唯一需要使用内联汇编器的情况是在一个循环内,该循环代表您的程序的大部分处理时间,而您知道的代码在编译器中的优化效果很差。此内联汇编器不符合这两个条件。尤其是因为它确实和它上面的C线完全一样!您可以完全删除asm()调用,而根本不更改程序的输出。

如果您的任务是使程序明显更快,但仅限于编辑该内联汇编程序,那么您就大错特错了。

关于c - 希望提高这种嵌入式 assembly 的效率,有人可以提供建议吗? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10490577/

10-13 05:55