2017-02-12 41 views
0

我在C以下流程:實現一個流 「(1)如果{...}否則,如果{...} ...(2)」 在大會

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


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

// some stuff2 

我不知道,我如何在Assembly中編碼?我的意思是,不是確切的入侵,而是流量。我應該使用標籤跳轉到內部if(something1){...}和「else if(something2)」嗎?我將如何返回到「//一些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){」如果第一個是真的?

我可以以某種方式實施,但我想知道如何更好地做到這一點。

+2

使用標籤是最明確的方法。 x86沒有進行有條件的調用,所以你最終會使用標籤。如果你喜歡,你可以在組裝之前用C * goto *嘗試。你也可以[參考一個編譯器](https://godbolt.org/g/h4iUR2)來獲得正確的靈感:) –

回答

0

,我看到它,你有兩個選擇:

  1. 使用功能,像你說的。那麼你所需要做的就是call func。 的好處是可讀性和更漂亮的代碼以及自動跳回到你調用函數的地方,但是它會花費你使用函數(設置寄存器並推送和彈出堆棧指針)的開銷。
  2. 使用標籤。這很簡單。但是,您需要聲明返回該函數的標籤,或者在某處保存返回地址,這會影響可讀性。

反正你有條件的一段代碼:

cmp [some_struc], SOME_CONST2 

似乎確定。

+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。我不會建議跳轉到Part1Part2然後跳回EndIf
這創建了意大利麪代碼。可讀性較差並且很快變得不易維護。