2

尝试在组装中执行以下操作:

#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编写此代码时尽可能少地使用。所以我想我的问题是:

  1. 在没有大量重新进入登记册的情况下,在议会中行使权力的最佳方式是什么?这甚至可能吗?
  2. 当我在汇编中循环时,我是否a已经想要设置 ' 的值?或者我可以在这里编写这样的for循环吗?(我可以避免while循环以节省空间)
4

1 回答 1

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:[ ...毫无意义的“ICC胶水”指令...]
  4006fd: bf 7c 0b 40 00 移动 $0x400b7c,%edi
  400702: 是 c5 07 00 00    移动 $0x7c5 ,%esi
  400707:[ ...毫无意义的“ICC胶水”指令...]
  40070e: ba 31 f6 ff ff mov     $0xfffff631 ,%edx
  400713: 33 c0 xor %eax,%eax
  400715:[ ...毫无意义的“ICC胶水”指令...]
  400719:e8 2a fe ff ff callq 400548 <printf@plt>
  40071e: 33 c0 xor %eax,%eax
  400720: 48 89 ec 移动 %rbp,%rsp
  400723:5d 弹出 %rbp
  400724:c3 retq

CLang (3.3) 也可以,它创建:

0000000000400b60 <主>:
  400b60: 50 推%rax
  400b61: bf 6c 0c 40 00 移动 $0x400c6c,%edi
  400b66: 是 c5 07 00 00    移动 $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 弹出 %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 <主>:
  400630: 48 83 ec 08 sub $0x8,%rsp
  400634: ba 31 f6 ff ff    移动 $0xfffff631 ,%edx
  400639: 是 c5 07 00 00    移动 $0x7c5 ,%esi
  40063e: bf 50 07 40 00 移动 $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 添加 $0x8,%rsp
  400650:c3 retq

士气:在这种情况下,最好的结果是尝试优化汇编器输出:)

于 2013-09-26T10:01:03.543 回答