2017-02-12 32 views
0

У меня есть следующий поток в C:Реализация потока "(1), если {...} еще если {...} ... (2)" в Ассамблее

// some stuff1 
//................ 


if (something1) { 
    func1(); 
    func2(); 
} else if (something2) { 
    func3(); 
    func4(); 
} 

// some stuff2 

Я удивляюсь, как я могу кодировать это в Assembly? Я имею в виду не точные наработки, а поток. Должен ли я использовать метки для перехода к тому, что внутри if (something1) {...} и «else if (something2)»? Как я тогда вернусь к «// some stuff2»?

; some stuff1 
    ; and then 

    cmp [some_struc], SOME_CONST 
    je .... ???? 

    cmp [some_struc], SOME_CONST2 
    je .... ???? 


    ; some stuff2 
    ; how to better get back here? 
    cmp rax, 0 

Или я должен назвать их функциями? Тогда как бы я пропустил второй «else if (something2) {», если 1-й из них является истинным?

Я могу как-то реализовать, но я хочу знать, как лучше это делать.

+2

Использование ярлыков - самый четкий подход. x86 не имеет условных вызовов, поэтому вы все равно будете использовать ярлыки. Вы можете попробовать с C * goto *, прежде чем входить в сборку, если хотите. Вы также можете [проконсультироваться с компилятором] (https://godbolt.org/g/h4iUR2), чтобы получить правильное вдохновение :) –

ответ

0

Как я вижу у вас есть два варианта:

  1. Используйте функции, как вы сказали. то все, что вам нужно сделать, это call func. Преимущество - это читаемость и более гладкий код, а также автоматический переход обратно туда, где вы вызывали эту функцию, но это будет стоить вам накладных расходов на использование функции (настройка регистров и нажатие и выскакивание указателя стека).
  2. Используйте этикетки. это просто. Но вам нужно будет объявить метку для возврата к функции или сохранить адрес возврата где-нибудь, что влияет на читаемость.

В любом случае ваш условный кусок кода:

cmp [some_struc], SOME_CONST2 

кажется OK.

+0

Можете ли вы подробно остановиться на своем первом вопросе? Точно, как он подходит для управления потоком управления, поскольку звонки безусловны? OP все равно придется использовать ярлыки. Вы также можете уточнить, что второй 'cmp ...' должен принимать во внимание, что находится на ветке 'else' первого. –

+0

, конечно, ему нужны метки для части if и else, я говорил о вызовах функций (у него есть выбор, использовать ли функцию или только метку с тем же кодом). –

1

Я бы сказал, что это во многом зависит от того, сколько кода у вас есть в этих {...} блоках.
Если есть ограниченный код в них используют:

cmp [some_struc], SOME_CONST 
    jne Else 
    {...} 
    jmp EndIf 
Else: 
    cmp [some_struc], SOME_CONST2 
    jne EndIf 
    {...} 
EndIf: 
    cmp rax, 0 

Если есть еще код:

cmp [some_struc], SOME_CONST 
    jne Else 
    call Part1 
    jmp EndIf 
Else: 
    cmp [some_struc], SOME_CONST2 
    jne EndIf 
    call Part2 
EndIf: 
    cmp rax, 0 

Part1: 
    {...} 
    ret 
Part2: 
    {...} 
    ret 

Лучшее использование call. Я бы не советовал прыгать на Часть 1 или Часть 2, а затем вернуться обратно к EndIf.
Это создает код спагетти. Менее читаемый и быстро становится менее ремонтопригодным.