2017-02-12 45 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
这创建了意大利面代码。可读性较差并且很快变得不易维护。