在汇编中实现流程“(1)if {...} else {...} ...(2)”

时间:2017-02-12 14:18:56

标签: assembly x86 nasm

我在C中有以下流程:

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


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

// some stuff2

我想知道,我如何在大会中对其进行编码?我的意思是,不是确切的说明,而是流程。如果(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 

或者我应该将它们称为功能?然后我怎么会跳过第二个“否则if(something2){”如果第一个是真的?

我可以用某种方式实现,但我想知道如何做得更好。

2 个答案:

答案 0 :(得分: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。我不建议跳转到 Part1 Part2 ,然后跳回 EndIf
这会创建意大利面条代码。可读性较差,维护速度较快。

答案 1 :(得分:0)

我认为你有两种选择:

  1. 使用像你说的功能。那么你需要做的只是call func。 优点是可读性和更光滑的代码以及自动跳回到您调用函数的位置,但它将花费您使用函数的开销(设置寄存器并推送和弹出堆栈指针)。
  2. 使用标签。这很简单。但是你需要声明一个标签来回到函数,或者在某处保存返回地址,这会影响可读性。
  3. 无论如何你的条件代码:

    cmp [some_struc], SOME_CONST2 
    

    似乎没问题。