GAS组装:开关-默认案例触发

时间:2020-04-17 12:31:49

标签: gcc assembly gnu-assembler

我正在分析如何将开关从C转换为组合(GAS)。我不了解GAS的窍门是如何触发“下边缘”默认设置的。

“更高边缘”存在条件跳转:

cmpl    $8, %eax
ja  .L2

“下边缘”没有条件跳转,只是跳转到跳转表中

那么,如何处理“较低”的默认设置? 例如当我输入10-显示DEFAULT

-------------我认为隐藏了窍门的部分代码 (交换机的范围是11-19,数字不均匀)

    call    scanf              #switch argument is in %eax
    movl    -4(%rbp), %eax 
    subl    $11, %eax
    cmpl    $8, %eax
    ja  .L2                   # higher edge default
    movl    %eax, %eax
    leaq    0(,%rax,4), %rdx
    leaq    .L4(%rip), %rax
    movl    (%rdx,%rax), %eax
    movslq  %eax, %rdx
    leaq    .L4(%rip), %rax
    addq    %rdx, %rax
    jmp *%rax

-----------下面是源代码

C代码:

#include <stdio.h>

int main()
{
    int a;
    printf("Insert a number : ");
    scanf("%d",&a);

    switch(a)
    {
        case 11: 
            printf("ELEVEN\n");
            break;
        case 13:
            printf("THIRTEEN\n");
            break;
        case 15:
            printf("FIFTEEN\n");
            break;
        case 17:
            printf("SEVENTEEN\n");
            break;
        case 19:
            printf("NINETEEN\n");
            break;
        default:
            printf("DEFAULT\n");
            break;
    }
    return 0;
}

GAS代码:

    .file   "switch1.c"
    .text
    .def    __main; .scl    2;  .type   32; .endef
    .section .rdata,"dr"
.LC0:
    .ascii "Insert a number : \0"
.LC1:
    .ascii "%d\0"
.LC2:
    .ascii "ELEVEN\0"
.LC3:
    .ascii "THIRTEEN\0"
.LC4:
    .ascii "FIFTEEN\0"
.LC5:
    .ascii "SEVENTEEN\0"
.LC6:
    .ascii "NINETEEN\0"
.LC7:
    .ascii "DEFAULT\0"
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    pushq   %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe   %rbp, 0
    subq    $48, %rsp
    .seh_stackalloc 48
    .seh_endprologue
    call    __main
    leaq    .LC0(%rip), %rcx
    call    printf
    leaq    -4(%rbp), %rax
    movq    %rax, %rdx
    leaq    .LC1(%rip), %rcx
    call    scanf
    movl    -4(%rbp), %eax
    subl    $11, %eax
    cmpl    $8, %eax
    ja  .L2
    movl    %eax, %eax
    leaq    0(,%rax,4), %rdx
    leaq    .L4(%rip), %rax
    movl    (%rdx,%rax), %eax
    movslq  %eax, %rdx
    leaq    .L4(%rip), %rax
    addq    %rdx, %rax
    jmp *%rax
    .section .rdata,"dr"
    .align 4
.L4:
    .long   .L3-.L4
    .long   .L2-.L4
    .long   .L5-.L4
    .long   .L2-.L4
    .long   .L6-.L4
    .long   .L2-.L4
    .long   .L7-.L4
    .long   .L2-.L4
    .long   .L8-.L4
    .text
.L3:
    leaq    .LC2(%rip), %rcx
    call    puts
    jmp .L9
.L5:
    leaq    .LC3(%rip), %rcx
    call    puts
    jmp .L9
.L6:
    leaq    .LC4(%rip), %rcx
    call    puts
    jmp .L9
.L7:
    leaq    .LC5(%rip), %rcx
    call    puts
    jmp .L9
.L8:
    leaq    .LC6(%rip), %rcx
    call    puts
    jmp .L9
.L2:
    leaq    .LC7(%rip), %rcx
    call    puts
    nop
.L9:
    movl    $0, %eax
    addq    $48, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .ident  "GCC: (GNU) 7.4.0"
    .def    printf; .scl    2;  .type   32; .endef
    .def    scanf;  .scl    2;  .type   32; .endef
    .def    puts;   .scl    2;  .type   32; .endef

0 个答案:

没有答案