尝试在装配中执行以下操作:
#include <stdio.h>
main(){
int a,b,c=0,d=0;
for(a = -3; a >= 3; a++){
b = a*a*a*a*a*a*a - a*a*a*a*4 - a*a*a + a*a*7 + 30*a;
if(b>=c){
c=b;
}
if(b<=d){
d=b;
}
}
printf("The max value is" + c + "\n");
printf("The min value is" + d + "\n");
}
我没有在汇编中编写代码,并且我希望能够在查看汇编语言时理解我的代码,所以简单地将其转换为使用gcc的汇编是不可能的。
我的目标是在制作此代码时尽可能少地使用nop
。所以我想我的问题是:
a
的值?或者可以
我在这里编程就像这样循环? (我可以避免循环以节省空间)答案 0 :(得分:0)
这段代码是编译器优化可以做的一个很好的例子。假设您的意思是for (a = -3; a <= 3; a++) ...
,那么您可以将其重新编码为:
#include <stdio.h>
#define val(a) (a*a*a*a*a*a*a - a*a*a*a*4 - a*a*a + a*a*7 + 30*a)
#define MIN(X, Y) ((X) > (Y) ? (Y) : (X))
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
int main(int argc, char **argv)
{
int c = 0, d = 0, a;
for (a = -3; a <= 3; a++)
c = MAX(val(a), c), d = MIN(val(a), d);
printf("max value is %d,\nmin value is %d\n", c, d);
return 0;
}
英特尔的ICC将其直接转变为:
4006f9: [ ... meaningless "ICC glue" instruction ... ] 4006fd: bf 7c 0b 40 00 mov $0x400b7c,%edi 400702: be c5 07 00 00 mov $0x7c5,%esi 400707: [ ... meaningless "ICC glue" instruction ... ] 40070e: ba 31 f6 ff ff mov $0xfffff631,%edx 400713: 33 c0 xor %eax,%eax 400715: [ ... meaningless "ICC glue" instruction ... ] 400719: e8 2a fe ff ff callq 400548 <printf@plt> 40071e: 33 c0 xor %eax,%eax 400720: 48 89 ec mov %rbp,%rsp 400723: 5d pop %rbp 400724: c3 retq
CLang(3.3)也可以,它创造:
0000000000400b60 <main>: 400b60: 50 push %rax 400b61: bf 6c 0c 40 00 mov $0x400c6c,%edi 400b66: be c5 07 00 00 mov $0x7c5,%esi 400b6b: ba 31 f6 ff ff mov $0xfffff631,%edx 400b70: 30 c0 xor %al,%al 400b72: e8 39 fd ff ff callq 4008b0 <printf@plt> 400b77: 31 c0 xor %eax,%eax 400b79: 5a pop %rdx 400b7a: c3 retq在这种情况下,GCC(直到并包括4.8.1)似乎无法进行编译时计算,而在展开循环时,它会插入一系列乘法,条件移动/ SSE最小/最大指令。
但是如果你在代码中明确地展开循环,那么你得到:
c = MAX(val(-3), 0); d = MIN(val(-3), 0);
c = MAX(val(-2), c); d = MIN(val(-2), d);
c = MAX(val(-1), c); d = MIN(val(-1), d);
c = MAX(val(0), c); d = MIN(val(0), d);
c = MAX(val(1), c); d = MIN(val(1), d);
c = MAX(val(2), c); d = MIN(val(2), d);
c = MAX(val(3), c); d = MIN(val(3), d);
并且GCC能够在编译时计算它:
0000000000400630 <main>: 400630: 48 83 ec 08 sub $0x8,%rsp 400634: ba 31 f6 ff ff mov $0xfffff631,%edx 400639: be c5 07 00 00 mov $0x7c5,%esi 40063e: bf 50 07 40 00 mov $0x400750,%edi 400643: 31 c0 xor %eax,%eax 400645: e8 79 fe ff ff callq 4004c0 <printf@plt> 40064a: 31 c0 xor %eax,%eax 40064c: 48 83 c4 08 add $0x8,%rsp 400650: c3 retq
士气:在这种情况下你得到的最好结果而不是试图优化汇编程序输出:)