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

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 <[email protected]+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

时间: 2024-08-25 07:45:05

ART世界探险(6) - 流程控制指令的相关文章

PHP中break及continue两个流程控制指令解析

<?php $arr = array( 'a' => '0a0', 'b' => '0b0', 'c' => '0c0', 'd' => '0d0', 'e' => '0e0', ); //********break********// //用来跳出目前执行的循环,并不再继续执行循环了. foreach($arr as $k => $v){ if($k == 'c'){ break; } $arr2[$k] = $v; } var_dump($arr2); /*

Angular——流程控制指令

基本介绍 (1)ng-repeat,类似于for循环,对数组进行遍历 (2)ng-switch on,ng-switch-when,类似于switch,case 基本使用 ng-repeat <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <b

浅析流程控制

浅析PHP流程控制 今天Qi号给小白们分享一下PHP基础(相互请教--): 下面是Qi号搜集的资料及自己的总结希望有所帮助: 什么是流程控制:在声明式的编程语言中,流程控制指令是指会改变程序运行顺序的指令,可能是运行不同位置的指令,或是在二段(或多段)程序中选择一个运行. 命令式编程:命令"机器"如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现. 声明式编程:告诉"机器"你想要的是什么(what),让机器想出如何去做(how). 等

python 学习之 基础篇三 流程控制

前言: 一. python中有严格的格式缩进,因为其在语法中摒弃了“{}”来包含代码块,使用严格的缩进来体现代码层次所以在编写代码的时候项目组要严格的统一器缩进语法,一个tab按键设置为四个空格来缩进,防止缩进不规范导致的启动失败. 二.在python中变量(标识符)命名和一般的高级语言没有什么不同都推荐使用,字母.下划线.数字命名,其中数字不能作为标识符的开头,python中变量名是区分大小写的(所以可以使用驼峰命名法去命名,也就是英文单词的字母首字母大写其余的小写).以下划线开头的标识符是有

漫谈程序控制流

作者: Liu, Martin 前言 随着JavaScript最新版本ECMAScript2015(ES6)的正式发布,以及babel这种ES6转ES5的工具的慢慢成熟, 在真实产品里使用ES6已经完全可行了. 写JS的朋友们,是时候点开es6features看一下了. 值得一提的是,ES6特性里竟然包括尾调用优化(tailcall),真是要点个赞.然而,这并没有什么用.   从ES6的Generator谈起 在ES6众多新特性里,Generator无疑是一个很酷的东西.cool在哪里?看cod

项目架构开发:业务逻辑层之领域驱动失血模型

前边我们构建了个数据访问层,功能虽然简单,但是基本够用了.传送门:项目架构开发:数据访问层 这次我们构建业务逻辑层 业务逻辑是一个项目.产品的核心,也是现实世界某种工作流程在代码层面的体现. 所以,业务逻辑的合理组织构造,或更真实地反映现实业务操作,对项目的成功与否非常重要 现在业界对业务逻辑层的开发,一般会参考Martin Fowler大师提出来的针对业务层开发的四种模式 分别是面向过程的事务脚本.表模块模式,面向对象的活动记录与领域开发模式 我们要做的就是领域驱动开发模式,注意标题中的“失血

Atitit.软件研发团队建设原理与概论 理论

培训 团队文化建设(内刊,ppt,书籍,杂志等) 梯队建设 技术储备人才的问题 团队建设--小红花评比. 团队建设--文化墙.doc 户外拓展 1. 团队建设游戏教练手册:全球众多著名机构优选课程(第二版)(职业培训师系列经典译著,世界探险组织御用培训教材 大型团队的热身游戏 小型团队的破冰游戏 建立信任游戏 沟通 解决问题型游戏 多团队解决问题型游戏 大总结 团队学习模型 游戏71 体验式学习 游戏72 EIAG模型 游戏73 学习区模型 游戏74 三环模型 游戏75 五原法模型 作者:: 绰

vue.js基础知识篇(2):指令详解

第三章:指令 1.语法 指令以v-打头,它的值限定为绑定表达式,它负责的是按照表达式的值应用某些行为到DOM上. 内部指令有v-show,v-else,v-model,v-repeat,v-for,v-text,v-el,v-html,v-on,v-bind,v-ref,v-pre,v-cloak,v-if. 2.内部指令 (1)控制元素的显示与否:v-if,v-show.v-else v-if是真实的条件渲染,根据表达式的true/false在DOM中生成或移除一个元素. 第一,这个指令是惰性

awk中文手册

1. 前言 有关本手册 : 这是一本awk学习指引, 其重点着重于 : l        awk 适于解决哪些问题 ? l        awk 常见的解题模式为何 ? 为使读者快速掌握awk解题的模式及特性, 本手册系由一些较具代表性的范例及其题解所构成; 各范例由浅入深, 彼此间相互连贯,范例中并对所使用的awk语法及指令辅以必要的说明. 有关awk的指令, 函数,...等条列式的说明则收录于附录中, 以利读者往后撰写程序时查阅. 如此编排, 可让读者在短时间内顺畅地学会使用awk来解决问题