2017-02-20 58 views
1

Я пытаюсь имитировать следующий код, который должен напечатать 1 2 в сборке:Ассамблея x86-64: по умолчанию на коммутаторе заявление

a=1 
    switch(a) { 
      default: print 1; 
      case 2: print 2; 
    } 

и это то, что у меня есть:

movq $1, a 
    pushq a 
    popq %rdx 
    cmp $1, %rdx 
    jne if_0 
    jmp if_1 
if_0: 
    movq $1, %rsi 
    pushq %rsi 
    movq $format, %rdi 
    popq %rsi 
    pushq %rbp 
    call printf 
    movq %rbp, %rsp 
    popq %rbp 
    jmp if_2 
if_1: 
    movq $2, %rsi 
    pushq %rsi 
    popq %r11 
    cmpq %rdx, %r11 
    je if_2 
    jne if_3 
if_2: 
    movq $2, %rsi 
    pushq %rsi 
    movq $format, %rdi 
    popq %rsi 
    pushq %rbp 
    call printf 
    movq %rbp, %rsp 
    popq %rbp 
    jmp if_4 
if_3: 
if_4: 
    jmp switch_0 

Вверху, я только сравниваю переменную с 1, потому что я не уверен, что делать. Как я могу смотреть в будущее и видеть, что a не равен 2, прежде чем делать случай по умолчанию?

+0

Непонятно, с чем вы столкнулись. Вам не нужно проверять случаи в порядке, указанном в источнике. Очевидно, что вы хотите оставить «default» последним, если ничего не сопоставить. – Jester

+0

Несколько языков применяют 'default:' как последнюю вещь в 'case', поэтому ваш пример недействителен, но предположим, что это возможно. Другой способ написать этот пример: 'if (2! = A) {print 1; } print 2; '... но всегда как' a = 1', вы можете просто '{print 1; печать 2; } 'без какой-либо логики. – Ped7g

ответ

2

Вы действуете как компилятор, так что вы можете «заглянуть в будущее» во всех случаях, и видим, что default дело берется, если переключатель не2.

Или, если вы еще один «компилятор», вы можете видеть, что код всегда будет печатать 1 2 и вообще не делать сравнения.

+0

«код всегда будет печатать 1», только если число не равно 2, правда? –

+0

@anc: Показанный код всегда использует значение '1'. Я не вижу какой-либо изменчивости в коде, поэтому на самом деле не нужно обходиться со значением вообще: просто распечатайте результат. – wallyk

2

Ваш код кажется сложным.

Посмотрите на код C и соответствующий код ASM

int printer(int a) 
{ 
    switch(a) 
    { 
      default: printf("%s","1"); 
      case 2: printf("%s","2"); 
    } 
} 

Да - Я знаю, что вы установите = 1 - но чем это не имеет никакого смысла сравнивать, если вы знаете, результат заранее. Ниже не оптимизированного результата ASM - есть putchar, потому что строка - одна буква, но это может быть изменено на printf по желанию.

printer(int): 
     push rbp 
     mov  rbp, rsp 
     sub  rsp, 16 
     mov  DWORD PTR [rbp-4], edi 
     mov  eax, DWORD PTR [rbp-4] 
     cmp  eax, 2 
     je  .L5 
     mov  edi, 49 
     call putchar 
.L5: 
     mov  edi, 50 
     call putchar 
     nop 
     leave 
     ret 

С оптимизацией это еще проще

printer(int): 
     cmp  edi, 2 
     jne  .L13 
     mov  edi, 50 
     jmp  putchar 
.L13: 
     sub  rsp, 8 
     mov  edi, 49 
     call putchar 
     mov  edi, 50 
     add  rsp, 8 
     jmp  putchar 

Вы, наверное, заметили Gcc трюк - он снимал кадр стека и инструкции в отставке в целом.

 Смежные вопросы

  • Нет связанных вопросов^_^