汇编C switch语句 - 它是如何工作的?

时间:2017-03-16 03:48:29

标签: assembly switch-statement

我正在读一本关于程序集切换语句的书,当输入n为大小写时,代码有case / branches:100,102,103,104,106。它通过从n减去100来简化跳转表,然后如果结果大于6,它转到L2中的默认情况,否则它将转到与%eax中的值匹配的相应分支。

我的问题是:

  1. 如果是,如果跳转表的索引保存在jmp *.L7(,%eax)中,则第7行不是%eax

  2. 为什么他们通过ja .L2将数字更改为第5行中的无符号?

  3. int x位于%ebp+8int n位于%ebp+12

     movl 8(%ebp), %edx 
     movl 12(%ebp), %eax 
     subl $100, %eax 
     cmpl $6, %eax 
     ja .L2 
     jmp *.L7(,%eax,4) 
    .L2: 
     movl $0, %eax 
     jmp .L8 
    .L5: 
     movl %edx, %eax 
    jmp .L9 
     .L3: 
     leal (%edx,%edx,2), %eax 
     leal (%edx,%eax,4), %eax 
     jmp .L8 
    .L4: 
     leal 10(%edx), %eax 
    .L9: 
     addl $11, %eax 
     jmp .L8 
    .L6: 
     movl %edx, %eax 
     imull %edx, %eax 
    .L8: 
    

    跳转表:

    .section .rodata
    .align 4 Align       
    .L7:
    .long .L3         //Case 100: loc_A
    .long .L2         //Case 101: loc_def
    .long .L4         //Case 102: loc_B
    .long .L5        //Case 103: loc_C
    .long .L6        //Case 104: loc_D
    .long .L2       //Case 105: loc_def
    .long .L6        //Case 106: loc_D
    

1 个答案:

答案 0 :(得分:3)

  如果跳转表的索引保存在jmp *.L7(,%eax)中,

第7行是不是%eax

跳转表中的每个条目都是long,即4个字节。因此,eax缩放为4。

  

为什么他们通过ja .L2将数字改为第5行中的无符号?

重点是排除任何小于100且大于106的数字。我认为它排除了大于106的值是显而易见的。

所以,让我们说n小于100,例如99.如果我们从那里减去100,我们得到-1,当被视为无符号的32位值时是4294967295,这显然是"高于" 6,跳转到.L2就像它应该的那样。

subl $100, %eax   ; eax = 99-100 == -1
cmpl $6, %eax     ; set flags based on -1 - 6 == -7 => ZF=0 and CF=0
ja .L2            ; jump if ZF=0 and CF=0