码迷,mamicode.com
首页 > 其他好文 > 详细

ART世界探险(6) - 流程控制指令

时间:2016-07-25 07:05:39      阅读:620      评论:0      收藏:0      [点我收藏+]

标签:

ART世界探险(6) - 流程控制指令

分支结构

Java分支结构

我们先来个最简单的,比较大小吧。

    public static long bigger(long a, long b){
        if(a>=b){
            return a;
        }else{
            return b;
        }
    }

    public static int less(int a,int b){
        if(a<=b){
            return a;
        }else{
            return b;
        }
    }

看看Java字节码是个什么样子:

  public static long bigger(long, long);
    Code:
       0: lload_0
       1: lload_2
       2: lcmp
       3: iflt          8
       6: lload_0
       7: lreturn
       8: lload_2
       9: lreturn

  public static int less(int, int);
    Code:
       0: iload_0
       1: iload_1
       2: if_icmpgt     7
       5: iload_0
       6: ireturn
       7: iload_1
       8: ireturn

lcmp是两个长整型做比较,结果影响标志位。然后iflt判断是否是小于(lt=less than),如果是则跳到8 ,不是则继续往下走。

普通整型的判断和比较在同一条指令里,if_icmpgt是判大于(gt=greater than),如果大于则跳转到7。

ARM的分支结构

对于这种根据不同情况选择不同值的语句,ARM在设计时专门有一条强大的csel指令,专门做这个事情。
先用cmp指令比较两个值,然后设置条件,ge是大于或等于,le是小于或等于。如果条件满足,则x0就是x0,否则x0取x1的值。

000000000000079c <_Z6biggerll>:
 79c:   eb01001f    cmp x0, x1
 7a0:   9a81a000    csel    x0, x0, x1, ge
 7a4:   d65f03c0    ret

00000000000007a8 <_Z4lessii>:
 7a8:   6b01001f    cmp w0, w1
 7ac:   1a81d000    csel    w0, w0, w1, le
 7b0:   d65f03c0    ret

Thumb2指令的分支结构

csel这样的指令需要32位的长度才放得下. Thumb2本着能省则省的原则,改用16位的条件mov指令来实现,可以节省2个字节指令空间。

0000101c <_Z6biggerll>:
    101c:   4288        cmp r0, r1
    101e:   bfb8        it  lt
    1020:   4608        movlt   r0, r1
    1022:   4770        bx  lr

00001024 <_Z4lessii>:
    1024:   4288        cmp r0, r1
    1026:   bfa8        it  ge
    1028:   4608        movge   r0, r1
    102a:   4770        bx  lr

Thumb指令的分支结构

Thumb指令没有带条件的mov操作,更不可能有csel这样复杂的指令了。那也没问题,返璞归真,我们直接跳转就是了呗?
bge.n,是说大于或等于,也就是不小于的时候直接跳到12aa,就是bx lr返回这条指令上去。

adds r0, r1, #0其实也可以翻译成movs r0,r1。前面我们讲过,movs r0,r1其实是adds r0, r1, #0的别名。本质上是一回事。

000012a4 <_Z6biggerll>:
    12a4:   4288        cmp r0, r1
    12a6:   da00        bge.n   12aa <_Z6biggerll+0x6>
    12a8:   1c08        adds    r0, r1, #0
    12aa:   4770        bx  lr

000012ac <_Z4lessii>:
    12ac:   4288        cmp r0, r1
    12ae:   dd00        ble.n   12b2 <_Z4lessii+0x6>
    12b0:   1c08        adds    r0, r1, #0
    12b2:   4770        bx  lr

x86_64的分支结构

x86_64中也是有带有条件的赋值指令的。

0000000000000740 <_Z6biggerll>:
 740:   48 39 f7                cmp    %rsi,%rdi
 743:   48 89 f0                mov    %rsi,%rax
 746:   48 0f 4d c7             cmovge %rdi,%rax
 74a:   c3                      retq   
 74b:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

0000000000000750 <_Z4lessii>:
 750:   39 f7                   cmp    %esi,%edi
 752:   89 f0                   mov    %esi,%eax
 754:   0f 4e c7                cmovle %edi,%eax
 757:   c3                      retq   
 758:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
 75f:   00 

x86的分支结构

cmov在x86上也是有的。

00000630 <_Z6biggerll>:
 630:   8b 44 24 04             mov    0x4(%esp),%eax
 634:   8b 54 24 08             mov    0x8(%esp),%edx
 638:   39 d0                   cmp    %edx,%eax
 63a:   0f 4c c2                cmovl  %edx,%eax
 63d:   c3                      ret    
 63e:   66 90                   xchg   %ax,%ax

00000640 <_Z4lessii>:
 640:   8b 44 24 04             mov    0x4(%esp),%eax
 644:   8b 54 24 08             mov    0x8(%esp),%edx
 648:   39 d0                   cmp    %edx,%eax
 64a:   0f 4f c2                cmovg  %edx,%eax
 64d:   c3                      ret    
 64e:   66 90                   xchg   %ax,%ax

mips64的分支结构

感觉上罗嗦了一点,但是本质上跟csel是一样的。

0000000000000c00 <_Z6biggerll>:
 c00:   0085182a    slt v1,a0,a1
 c04:   00832035    seleqz  a0,a0,v1
 c08:   00a31037    selnez  v0,a1,v1
 c0c:   03e00009    jr  ra
 c10:   00821025    or  v0,a0,v0
 c14:   00000000    nop

0000000000000c18 <_Z4lessii>:
 c18:   00a4102a    slt v0,a1,a0
 c1c:   00a22837    selnez  a1,a1,v0
 c20:   00822035    seleqz  a0,a0,v0
 c24:   03e00009    jr  ra
 c28:   00a41025    or  v0,a1,a0
 c2c:   00000000    nop

mips的分支结构:

比起上面64位的,是不是感觉更加清爽呢?

00000710 <_Z6biggerll>:
 710:   0085102a    slt v0,a0,a1
 714:   0082280a    movz    a1,a0,v0
 718:   03e00008    jr  ra
 71c:   00a01021    move    v0,a1

00000720 <_Z4lessii>:
 720:   00a4102a    slt v0,a1,a0
 724:   0082280a    movz    a1,a0,v0
 728:   03e00008    jr  ra
 72c:   00a01021    move    v0,a1

循环结构

我们写一个while循环,一个do while循环和一个for循环来测试一下,其实本质上差不多是一回事情:

    public static long testWhile(int value){
        int i=0;
        long sum = 0;
        while(i<=value){
            sum += i;
            i++;
        }
        return sum;
    }

    public static long testDoWhile(int value){
        long sum = 0;
        int i=0;
        do{
            sum += i;
            i++;
        }while(i<value);
        return sum;
    }

    public static long testFor(int value){
        long sum = 0;
        for(int i=0;i<=value;i++){
            sum += i;
        }
        return sum;
    }

Java字节码的循环结构

我们先来解释其中第一个吧。这其中唯一遇到的新指令是无条件跳转的goto指令。
其中第6标号的if_icmpgt我们在分支中学过了。

  public static long testWhile(int);
    Code:
       0: iconst_0
       1: istore_1
       2: lconst_0
       3: lstore_2
       4: iload_1
       5: iload_0
       6: if_icmpgt     20
       9: lload_2
      10: iload_1
      11: i2l
      12: ladd
      13: lstore_2
      14: iinc          1, 1
      17: goto          4
      20: lload_2
      21: lreturn

后面两个与上面的非常类似。只是指令顺序上稍有不同而己。

  public static long testDoWhile(int);
    Code:
       0: lconst_0
       1: lstore_1
       2: iconst_0
       3: istore_3
       4: lload_1
       5: iload_3
       6: i2l
       7: ladd
       8: lstore_1
       9: iinc          3, 1
      12: iload_3
      13: iload_0
      14: if_icmplt     4
      17: lload_1
      18: lreturn

  public static long testFor(int);
    Code:
       0: lconst_0
       1: lstore_1
       2: iconst_0
       3: istore_3
       4: iload_3
       5: iload_0
       6: if_icmpgt     20
       9: lload_1
      10: iload_3
      11: i2l
      12: ladd
      13: lstore_1
      14: iinc          3, 1
      17: goto          4
      20: lload_1
      21: lreturn

Thumb的循环结构

我们下面来看看16位的Thumb指令是如何实现循环的。
value参数传进来在r0。将r2,r3清0, r2与参数传进来的r0比较,如果0已经比r0大了,循环结束,将结果r3赋给r0,返回。
如果0比r0小,则继续循环,r3结果等于r3值加上r2值,r2值随后加1。然后无条件回12b8那条比较语句,再判断r2是不是大于r0,如此循环。

000012b4 <_Z9testWhilei>:
    12b4:   2300        movs    r3, #0
    12b6:   1c1a        adds    r2, r3, #0
    12b8:   4282        cmp r2, r0
    12ba:   dc02        bgt.n   12c2 <_Z9testWhilei+0xe>
    12bc:   189b        adds    r3, r3, r2
    12be:   3201        adds    r2, #1
    12c0:   e7fa        b.n 12b8 <_Z9testWhilei+0x4>
    12c2:   1c18        adds    r0, r3, #0
    12c4:   4770        bx  lr

后面两个也是语句位置变了变,本质是一样的。

000012c6 <_Z11testDoWhilei>:
    12c6:   2300        movs    r3, #0
    12c8:   1c1a        adds    r2, r3, #0
    12ca:   18d2        adds    r2, r2, r3
    12cc:   3301        adds    r3, #1
    12ce:   4283        cmp r3, r0
    12d0:   dbfb        blt.n   12ca <_Z11testDoWhilei+0x4>
    12d2:   1c10        adds    r0, r2, #0
    12d4:   4770        bx  lr

000012d6 <_Z7testFori>:
    12d6:   2300        movs    r3, #0
    12d8:   1c1a        adds    r2, r3, #0
    12da:   4283        cmp r3, r0
    12dc:   dc02        bgt.n   12e4 <_Z7testFori+0xe>
    12de:   18d2        adds    r2, r2, r3
    12e0:   3301        adds    r3, #1
    12e2:   e7fa        b.n 12da <_Z7testFori+0x4>
    12e4:   1c10        adds    r0, r2, #0
    12e6:   4770        bx  lr

Thumb2的循环结构

v7a的循环结构

我们只看一个吧,除了地址不同,与前面的Thumb指令完全相同,所以略过不讲了。

0000102c <_Z9testWhilei>:
    102c:   2300        movs    r3, #0
    102e:   461a        mov r2, r3
    1030:   4282        cmp r2, r0
    1032:   dc02        bgt.n   103a <_Z9testWhilei+0xe>
    1034:   4413        add r3, r2
    1036:   3201        adds    r2, #1
    1038:   e7fa        b.n 1030 <_Z9testWhilei+0x4>
    103a:   4618        mov r0, r3
    103c:   4770        bx  lr

mips的循环结构

我们再看下mips的三个循环结构,也跟上面所讲的差不多。

00000730 <_Z9testWhilei>:
 730:   04800009    bltz    a0,758 <_Z9testWhilei+0x28>
 734:   24840001    addiu   a0,a0,1
 738:   00001021    move    v0,zero
 73c:   00001821    move    v1,zero
 740:   00431021    addu    v0,v0,v1
 744:   24630001    addiu   v1,v1,1
 748:   1464fffe    bne v1,a0,744 <_Z9testWhilei+0x14>
 74c:   00431021    addu    v0,v0,v1
 750:   03e00008    jr  ra
 754:   00431023    subu    v0,v0,v1
 758:   03e00008    jr  ra
 75c:   00001021    move    v0,zero

00000760 <_Z11testDoWhilei>:
 760:   00001821    move    v1,zero
 764:   00001021    move    v0,zero
 768:   00431021    addu    v0,v0,v1
 76c:   24630001    addiu   v1,v1,1
 770:   0064282a    slt a1,v1,a0
 774:   14a0fffd    bnez    a1,76c <_Z11testDoWhilei+0xc>
 778:   00431021    addu    v0,v0,v1
 77c:   03e00008    jr  ra
 780:   00431023    subu    v0,v0,v1

00000784 <_Z7testFori>:
 784:   04800009    bltz    a0,7ac <_Z7testFori+0x28>
 788:   24840001    addiu   a0,a0,1
 78c:   00001821    move    v1,zero
 790:   00001021    move    v0,zero
 794:   00431021    addu    v0,v0,v1
 798:   24630001    addiu   v1,v1,1
 79c:   1464fffe    bne v1,a0,798 <_Z7testFori+0x14>
 7a0:   00431021    addu    v0,v0,v1
 7a4:   03e00008    jr  ra
 7a8:   00431023    subu    v0,v0,v1
 7ac:   03e00008    jr  ra
 7b0:   00001021    move    v0,zero

mips64的循环结构

64位的除了加减法换成支持64位的了,其它没有变化。

0000000000000c30 <_Z9testWhilei>:
 c30:   0480000a    bltz    a0,c5c <_Z9testWhilei+0x2c>
 c34:   64840001    daddiu  a0,a0,1
 c38:   0000182d    move    v1,zero
 c3c:   0000102d    move    v0,zero
 c40:   0043102d    daddu   v0,v0,v1
 c44:   00000000    nop
 c48:   64630001    daddiu  v1,v1,1
 c4c:   1464fffe    bne v1,a0,c48 <_Z9testWhilei+0x18>
 c50:   0043102d    daddu   v0,v0,v1
 c54:   03e00009    jr  ra
 c58:   0043102f    dsubu   v0,v0,v1
 c5c:   03e00009    jr  ra
 c60:   0000102d    move    v0,zero
 c64:   00000000    nop

0000000000000c68 <_Z11testDoWhilei>:
 c68:   0000182d    move    v1,zero
 c6c:   0000102d    move    v0,zero
 c70:   0043102d    daddu   v0,v0,v1
 c74:   64630001    daddiu  v1,v1,1
 c78:   00032800    sll a1,v1,0x0
 c7c:   5ca4fffc    bltc    a1,a0,c70 <_Z11testDoWhilei+0x8>
 c80:   00000000    nop
 c84:   d81f0000    jrc ra

0000000000000c88 <_Z7testFori>:
 c88:   0480000a    bltz    a0,cb4 <_Z7testFori+0x2c>
 c8c:   64840001    daddiu  a0,a0,1
 c90:   0000182d    move    v1,zero
 c94:   0000102d    move    v0,zero
 c98:   0043102d    daddu   v0,v0,v1
 c9c:   00000000    nop
 ca0:   64630001    daddiu  v1,v1,1
 ca4:   1464fffe    bne v1,a0,ca0 <_Z7testFori+0x18>
 ca8:   0043102d    daddu   v0,v0,v1
 cac:   03e00009    jr  ra
 cb0:   0043102f    dsubu   v0,v0,v1
 cb4:   03e00009    jr  ra
 cb8:   0000102d    move    v0,zero
 cbc:   00000000    nop

arm v8a的循环结构

下面我们看第一个while循环在v8a上的实现:
竟然动用了强大的NEON指令!

00000000000007c0 <_Z9testWhilei>:
 7c0:   2a0003e3    mov w3, w0
 7c4:   37f80643    tbnz    w3, #31, 88c <_Z9testWhilei+0xcc>
 7c8:   51000c60    sub w0, w3, #0x3
 7cc:   7100147f    cmp w3, #0x5
 7d0:   53027c00    lsr w0, w0, #2
 7d4:   11000464    add w4, w3, #0x1
 7d8:   11000400    add w0, w0, #0x1
 7dc:   531e7402    lsl w2, w0, #2
 7e0:   5400050d    b.le    880 <_Z9testWhilei+0xc0>
 7e4:   100005e5    adr x5, 8a0 <_Z9testWhilei+0xe0>
 7e8:   4f000484    movi    v4.4s, #0x4
 7ec:   4f000400    movi    v0.4s, #0x0
 7f0:   52800001    mov w1, #0x0                    // #0
 7f4:   3dc000a1    ldr q1, [x5]
 7f8:   0f20a422    sxtl    v2.2d, v1.2s
 7fc:   11000421    add w1, w1, #0x1
 800:   4f20a423    sxtl2   v3.2d, v1.4s
 804:   6b01001f    cmp w0, w1
 808:   4ea48421    add v1.4s, v1.4s, v4.4s
 80c:   4ee08440    add v0.2d, v2.2d, v0.2d
 810:   4ee08460    add v0.2d, v3.2d, v0.2d
 814:   54ffff28    b.hi    7f8 <_Z9testWhilei+0x38>
 818:   5ef1b800    addp    d0, v0.2d
 81c:   6b02009f    cmp w4, w2
 820:   4e083c00    mov x0, v0.d[0]
 824:   540002c0    b.eq    87c <_Z9testWhilei+0xbc>
 828:   11000444    add w4, w2, #0x1
 82c:   8b22c000    add x0, x0, w2, sxtw
 830:   6b04007f    cmp w3, w4
 834:   5400024b    b.lt    87c <_Z9testWhilei+0xbc>
 838:   11000841    add w1, w2, #0x2
 83c:   8b24c000    add x0, x0, w4, sxtw
 840:   6b01007f    cmp w3, w1
 844:   540001cb    b.lt    87c <_Z9testWhilei+0xbc>
 848:   11000c44    add w4, w2, #0x3
 84c:   8b21c000    add x0, x0, w1, sxtw
 850:   6b04007f    cmp w3, w4
 854:   5400014b    b.lt    87c <_Z9testWhilei+0xbc>
 858:   11001041    add w1, w2, #0x4
 85c:   8b24c000    add x0, x0, w4, sxtw
 860:   6b01007f    cmp w3, w1
 864:   540000cb    b.lt    87c <_Z9testWhilei+0xbc>
 868:   11001442    add w2, w2, #0x5
 86c:   8b21c000    add x0, x0, w1, sxtw
 870:   6b02007f    cmp w3, w2
 874:   8b22c001    add x1, x0, w2, sxtw
 878:   9a80a020    csel    x0, x1, x0, ge
 87c:   d65f03c0    ret
 880:   d2800000    mov x0, #0x0                    // #0
 884:   52800002    mov w2, #0x0                    // #0
 888:   17ffffe8    b   828 <_Z9testWhilei+0x68>
 88c:   d2800000    mov x0, #0x0                    // #0
 890:   d65f03c0    ret
 894:   d503201f    nop
 898:   d503201f    nop
 89c:   d503201f    nop
 8a0:   00000000    .inst   0x00000000 ; undefined
 8a4:   00000001    .inst   0x00000001 ; undefined
 8a8:   00000002    .inst   0x00000002 ; undefined
 8ac:   00000003    .inst   0x00000003 ; undefined

篇幅所限,另两个就不列举了。

x86_64的循环结构

x86不甘人后,也动用了MMX整数的SIMD指令来完成这个小循环。。。

0000000000000760 <_Z9testWhilei>:
 760:   85 ff                   test   %edi,%edi
 762:   0f 88 48 01 00 00       js     8b0 <_Z9testWhilei+0x150>
 768:   8d 47 fd                lea    -0x3(%rdi),%eax
 76b:   8d 77 01                lea    0x1(%rdi),%esi
 76e:   c1 e8 02                shr    $0x2,%eax
 771:   83 c0 01                add    $0x1,%eax
 774:   83 ff 0e                cmp    $0xe,%edi
 777:   8d 14 85 00 00 00 00    lea    0x0(,%rax,4),%edx
 77e:   0f 8e 4c 01 00 00       jle    8d0 <_Z9testWhilei+0x170>
 784:   66 0f 6f 1d 34 05 00    movdqa 0x534(%rip),%xmm3        # cc0 <Java_xulun_testcppjni2_TestJniCpp_test+0x30>
 78b:   00 
 78c:   31 c9                   xor    %ecx,%ecx
 78e:   66 0f 6f 0d 1a 05 00    movdqa 0x51a(%rip),%xmm1        # cb0 <Java_xulun_testcppjni2_TestJniCpp_test+0x20>
 795:   00 
 796:   66 0f ef c0             pxor   %xmm0,%xmm0
 79a:   66 0f 38 25 d1          pmovsxdq %xmm1,%xmm2
 79f:   83 c1 01                add    $0x1,%ecx
 7a2:   66 0f d4 c2             paddq  %xmm2,%xmm0
 7a6:   66 0f 6f d1             movdqa %xmm1,%xmm2
 7aa:   66 0f 73 da 08          psrldq $0x8,%xmm2
 7af:   39 c8                   cmp    %ecx,%eax
 7b1:   66 0f 38 25 d2          pmovsxdq %xmm2,%xmm2
 7b6:   66 0f fe cb             paddd  %xmm3,%xmm1
 7ba:   66 0f d4 c2             paddq  %xmm2,%xmm0
 7be:   77 da                   ja     79a <_Z9testWhilei+0x3a>
 7c0:   66 0f 6f c8             movdqa %xmm0,%xmm1
 7c4:   39 d6                   cmp    %edx,%esi
 7c6:   66 0f 73 d9 08          psrldq $0x8,%xmm1
 7cb:   66 0f d4 c1             paddq  %xmm1,%xmm0
 7cf:   66 48 0f 7e c0          movq   %xmm0,%rax
 7d4:   0f 84 ee 00 00 00       je     8c8 <_Z9testWhilei+0x168>
 7da:   48 63 ca                movslq %edx,%rcx
 7dd:   48 01 c8                add    %rcx,%rax
 7e0:   8d 4a 01                lea    0x1(%rdx),%ecx
 7e3:   39 cf                   cmp    %ecx,%edi
 7e5:   0f 8c d5 00 00 00       jl     8c0 <_Z9testWhilei+0x160>
 7eb:   48 63 c9                movslq %ecx,%rcx
 7ee:   48 01 c8                add    %rcx,%rax
 7f1:   8d 4a 02                lea    0x2(%rdx),%ecx
 7f4:   39 cf                   cmp    %ecx,%edi
 7f6:   0f 8c c4 00 00 00       jl     8c0 <_Z9testWhilei+0x160>
 7fc:   48 63 c9                movslq %ecx,%rcx
 7ff:   48 01 c8                add    %rcx,%rax
 802:   8d 4a 03                lea    0x3(%rdx),%ecx
 805:   39 cf                   cmp    %ecx,%edi
 807:   0f 8c b3 00 00 00       jl     8c0 <_Z9testWhilei+0x160>
 80d:   48 63 c9                movslq %ecx,%rcx
 810:   48 01 c8                add    %rcx,%rax
 813:   8d 4a 04                lea    0x4(%rdx),%ecx
 816:   39 cf                   cmp    %ecx,%edi
 818:   0f 8c a2 00 00 00       jl     8c0 <_Z9testWhilei+0x160>
 81e:   48 63 c9                movslq %ecx,%rcx
 821:   48 01 c8                add    %rcx,%rax
 824:   8d 4a 05                lea    0x5(%rdx),%ecx
 827:   39 cf                   cmp    %ecx,%edi
 829:   0f 8c 91 00 00 00       jl     8c0 <_Z9testWhilei+0x160>
 82f:   48 63 c9                movslq %ecx,%rcx
 832:   48 01 c8                add    %rcx,%rax
 835:   8d 4a 06                lea    0x6(%rdx),%ecx
 838:   39 cf                   cmp    %ecx,%edi
 83a:   0f 8c 80 00 00 00       jl     8c0 <_Z9testWhilei+0x160>
 840:   48 63 c9                movslq %ecx,%rcx
 843:   48 01 c8                add    %rcx,%rax
 846:   8d 4a 07                lea    0x7(%rdx),%ecx
 849:   39 cf                   cmp    %ecx,%edi
 84b:   7c 73                   jl     8c0 <_Z9testWhilei+0x160>
 84d:   48 63 c9                movslq %ecx,%rcx
 850:   48 01 c8                add    %rcx,%rax
 853:   8d 4a 08                lea    0x8(%rdx),%ecx
 856:   39 cf                   cmp    %ecx,%edi
 858:   7c 66                   jl     8c0 <_Z9testWhilei+0x160>
 85a:   48 63 c9                movslq %ecx,%rcx
 85d:   48 01 c8                add    %rcx,%rax
 860:   8d 4a 09                lea    0x9(%rdx),%ecx
 863:   39 cf                   cmp    %ecx,%edi
 865:   7c 59                   jl     8c0 <_Z9testWhilei+0x160>
 867:   48 63 c9                movslq %ecx,%rcx
 86a:   48 01 c8                add    %rcx,%rax
 86d:   8d 4a 0a                lea    0xa(%rdx),%ecx
 870:   39 cf                   cmp    %ecx,%edi
 872:   7c 4c                   jl     8c0 <_Z9testWhilei+0x160>
 874:   48 63 c9                movslq %ecx,%rcx
 877:   48 01 c8                add    %rcx,%rax
 87a:   8d 4a 0b                lea    0xb(%rdx),%ecx
 87d:   39 cf                   cmp    %ecx,%edi
 87f:   7c 3f                   jl     8c0 <_Z9testWhilei+0x160>
 881:   48 63 c9                movslq %ecx,%rcx
 884:   48 01 c8                add    %rcx,%rax
 887:   8d 4a 0c                lea    0xc(%rdx),%ecx
 88a:   39 cf                   cmp    %ecx,%edi
 88c:   7c 32                   jl     8c0 <_Z9testWhilei+0x160>
 88e:   48 63 c9                movslq %ecx,%rcx
 891:   48 01 c8                add    %rcx,%rax
 894:   8d 4a 0d                lea    0xd(%rdx),%ecx
 897:   39 cf                   cmp    %ecx,%edi
 899:   7c 25                   jl     8c0 <_Z9testWhilei+0x160>
 89b:   48 63 c9                movslq %ecx,%rcx
 89e:   83 c2 0e                add    $0xe,%edx
 8a1:   48 01 c8                add    %rcx,%rax
 8a4:   39 d7                   cmp    %edx,%edi
 8a6:   7c 38                   jl     8e0 <_Z9testWhilei+0x180>
 8a8:   48 63 d2                movslq %edx,%rdx
 8ab:   48 01 d0                add    %rdx,%rax
 8ae:   c3                      retq   
 8af:   90                      nop
 8b0:   31 c0                   xor    %eax,%eax
 8b2:   66 66 66 66 66 2e 0f    data16 data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
 8b9:   1f 84 00 00 00 00 00 
 8c0:   c3                      retq   
 8c1:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
 8c8:   c3                      retq   
 8c9:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
 8d0:   31 c0                   xor    %eax,%eax
 8d2:   31 d2                   xor    %edx,%edx
 8d4:   e9 01 ff ff ff          jmpq   7da <_Z9testWhilei+0x7a>
 8d9:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
 8e0:   c3                      retq   
 8e1:   66 66 66 66 66 66 2e    data16 data16 data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
 8e8:   0f 1f 84 00 00 00 00 
 8ef:   00 

x86的循环结构

32位的x86,仍然动用MMX等SIMD技术来处理这个小循环。

`asm
00000650 <_Z9testWhilei>:
650: 57 push %edi
651: 56 push %esi
652: 53 push %ebx
653: e8 c8 ff ff ff call 620 <__cxa_finalize@plt+0xc0>
658: 81 c3 90 19 00 00 add $0x1990,%ebx
65e: 8b 4c 24 10 mov 0x10(%esp),%ecx
662: 85 c9 test %ecx,%ecx
664: 0f 88 f6 00 00 00 js 760 <_Z9testWhilei+0x110>
66a: 8d 41 fd lea -0x3(%ecx),%eax
66d: 8d 71 01 lea 0x1(%ecx),%esi
670: c1 e8 02 shr $0x2,%eax
673: 83 c0 01 add $0x1,%eax
676: 83 f9 0d cmp $0xd,%ecx
679: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx
680: 0f 8e ca 00 00 00 jle 750 <_Z9testWhilei+0x100>
686: 66 0f 6f 93 c8 ea ff movdqa -0x1538(%ebx),%xmm2
68d: ff
68e: 31 ff xor %edi,%edi
690: 66 0f 6f 83 b8 ea ff movdqa -0x1548(%ebx),%xmm0
697: ff
698: 66 0f ef c9 pxor %xmm1,%xmm1
69c: 83 c7 01 add $0x1,%edi
69f: 66 0f fe c8 paddd %xmm0,%xmm1
6a3: 39 f8 cmp %edi,%eax
6a5: 66 0f fe c2 paddd %xmm2,%xmm0
6a9: 77 f1 ja 69c <_Z9testWhilei+0x4c>
6ab: 66 0f 6f c1 movdqa %xmm1,%xmm0
6af: 39 d6 cmp %edx,%esi
6b1: 66 0f 73 d8 08 psrldq $0x8,%xmm0
6b6: 66 0f fe c8 paddd %xmm0,%xmm1
6ba: 66 0f 6f c1 movdqa %xmm1,%xmm0
6be: 66 0f 73 d8 04 psrldq $0x4,%xmm0
6c3: 66 0f fe c8 paddd %xmm0,%xmm1
6c7: 66 0f 7e c8 movd %xmm1,%eax
6cb: 74 79 je 746 <_Z9testWhilei+0xf6>
6cd: 8d 72 01 lea 0x1(%edx),%esi
6d0: 01 d0 add %edx,%eax
6d2: 39 f1 cmp %esi,%ecx
6d4: 7c 70 jl 746 <_Z9testWhilei+0xf6>
6d6: 01 f0 add %esi,%eax
6d8: 8d 72 02 lea 0x2(%edx),%esi
6db: 39 f1 cmp %esi,%ecx
6dd: 7c 67 jl 746 <_Z9testWhilei+0xf6>
6df: 01 f0 add %esi,%eax
6e1: 8d 72 03 lea 0x3(%edx),%esi
6e4: 39 f1 cmp %esi,%ecx
6e6: 7c 5e jl 746 <_Z9testWhilei+0xf6>
6e8: 01 f0 add %esi,%eax
6ea: 8d 72 04 lea 0x4(%edx),%esi
6ed: 39 f1 cmp %esi,%ecx
6ef: 7c 55 jl 746 <_Z9testWhilei+0xf6>
6f1: 01 f0 add %esi,%eax
6f3: 8d 72 05 lea 0x5(%edx),%esi
6f6: 39 f1 cmp %esi,%ecx
6f8: 7c 4c jl 746 <_Z9testWhilei+0xf6>
6fa: 01 f0 add %esi,%eax
6fc: 8d 72 06 lea 0x6(%edx),%esi
6ff: 39 f1 cmp %esi,%ecx
701: 7c 43 jl 746 <_Z9testWhilei+0xf6>
703: 01 f0 add %esi,%eax
705: 8d 72 07 lea 0x7(%edx),%esi
708: 39 f1 cmp %esi,%ecx
70a: 7c 3a jl 746 <_Z9testWhilei+0xf6>
70c: 01 f0 add %esi,%eax
70e: 8d 72 08 lea 0x8(%edx),%esi
711: 39 f1 cmp %esi,%ecx
713: 7c 31 jl 746 <_Z9testWhilei+0xf6>
715: 01 f0 add %esi,%eax
717: 8d 72 09 lea 0x9(%edx),%esi
71a: 39 f1 cmp %esi,%ecx
71c: 7c 28 jl 746 <_Z9testWhilei+0xf6>
71e: 01 f0 add %esi,%eax
720: 8d 72 0a lea 0xa(%edx),%esi
723: 39 f1 cmp %esi,%ecx
725: 7c 1f jl 746 <_Z9testWhilei+0xf6>
727: 01 f0 add %esi,%eax
729: 8d 72 0b lea 0xb(%edx),%esi
72c: 39 f1 cmp %esi,%ecx
72e: 7c 16 jl 746 <_Z9testWhilei+0xf6>
730: 01 f0 add %esi,%eax
732: 8d 72 0c lea 0xc(%edx),%esi
735: 39 f1 cmp %esi,%ecx
737: 7c 0d jl 746 <_Z9testWhilei+0xf6>
739: 83 c2 0d add $0xd,%edx
73c: 01 f0 add %esi,%eax
73e: 39 d1 cmp %edx,%ecx
740: 8d 34 10 lea (%eax,%edx,1),%esi
743: 0f 4d c6 cmovge %esi,%eax
746: 5b pop %ebx
747: 5e pop %esi
748: 5f pop %edi
749: c3 ret
74a: 8d b6 00 00 00 00 lea 0x0(%esi),%esi
750: 31 c0 xor %eax,%eax
752: 31 d2 xor %edx,%edx
754: e9 74 ff ff ff jmp 6cd <_Z9testWhilei+0x7d>
759: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
760: 31 c0 xor %eax,%eax
762: eb e2 jmp 746 <_Z9testWhilei+0xf6>
764: 8d b6 00 00 00 00 lea 0x0(%esi),%esi
76a: 8d bf 00 00 00 00 lea 0x0(%edi),%edi

ART世界探险(6) - 流程控制指令

标签:

原文地址:http://blog.csdn.net/lusing/article/details/52020051

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!