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年前关闭。
谢谢大家对我的耐心。我只需要把头缠在我正在看的东西上。抱歉,请尝试学习和理解。
重新阅读了每个人的注释并浏览了几次代码后,我意识到我的问题针对了错误的方向。一世
我可以用简单的组装说明替换这两行吗?还是我必须做类似
编辑
我没有意识到我从帖子中忽略了这一点。显然,最重要的部分是Oli,感谢您指出这一点。
目标是用内联汇编代码替换附加程序中for循环内的两行代码。您必须从内联汇编代码中获得相同的输出。 (执行相同的结果,循环数相同)
C :
部件 :
输出:
出于优化目的,您需要了解的最重要的事情是它只能运行一次。不仅如此,它还执行着非常简单和快速的操作,如果使用C编写它也可能同样简单和快速。拥有这种内联汇编除了使程序更复杂之外没有意义,这是我的另一个原因认为这项任务有些奇怪。似乎到处都是红鲱鱼。
让我们逐行看一下汇编器。
第一行是将
第二行将变量1装入
第三行将变量2(
第四行将结果复制到输出变量(
其余各行按顺序(0,1,2)定义了我们刚才引用的变量,并且还告诉编译器您刚刚使用了
您只需在C语言中简单地添加即可轻松替换所有该汇编程序,而且速度不会降低。编译器非常聪明。
基本上,唯一需要使用内联汇编器的情况是在一个循环内,该循环代表您的程序的大部分处理时间,而您知道的代码在编译器中的优化效果很差。此内联汇编器不符合这两个条件。尤其是因为它确实和它上面的C线完全一样!您可以完全删除asm()调用,而根本不更改程序的输出。
如果您的任务是使程序明显更快,但仅限于编辑该内联汇编程序,那么您就大错特错了。
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