该C代码的哪一部分缺失或需要更改?

Jad*_*den 8 c assembly switch-statement

对于我的任务,我必须填写下面C代码的缺失部分.但是,我不确定哪些部分缺失或者我必须填写哪部分.我有一个示例汇编代码,此代码将生成,但不知道我必须更改哪些部分才能获得我的预期结果.我只是想澄清一下.

typedef enum {MODE_A, MODE_B, MODE_C, MODE_D, MODE_E} mode_t;
long switch3 (long *p1, long *p2, mode_t action) {
  long result = 0;
  switch(action){
  case MODE_A:
  case MODE_B:
  case MODE_C:
  case MODE_D:
  case MODE_E:
  default;
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

其他要点:

  • 可能存在应该在C代码中写入带有漏洞的情况
  • 代码显示了switch语句中枚举类型值的分支.(问:这究竟是什么意思?我的教授提供了一个我不理解的复杂定义.)

汇编代码结果示例:

# p1 in %rdi, p2 in %rsi, action in %edx
.L2:                         # MODE_E
      movl    $27, %eax
      ret
.L7:                         # MODE_A
      movl    (%rsi), %rax
      movq    (%rdi), %rdx
      movq     %rdx, (%rsi)
      ret
.L5:                         # MODE_B
      movq     (%rdi), %rax
      addq     (%rsi), %rax
      movq      %rax, (%rdi)
      ret
.L4:                         # MODE_C
      movq     $59, (%rdi)
      movq     (%rsi), %rax
      ret
.L3:                         # MODE_D
      movq     (%rsi), %rax
      movq      %rax, (%rdi)
      movl      $27, %eax
      ret
.L8:                         # default
      movl      $12, %eax
      ret
Run Code Online (Sandbox Code Playgroud)

jha*_*mon 8

由于这是一项任务,我不会给你代码.但这里有关于这两点的澄清.

switch() case通常被视为像块:

if(myvar == ...){
    //branch1
} else if(myvar == ...){
    //branch2
}
...
Run Code Online (Sandbox Code Playgroud)

每个if都是一个分支,在您的情况下,每个分支条件取决于Enum值.那应该回答这个branching on an enumerated type value in a switch statement问题.

我写的"一般"是因为实际上a switch case更像是asm jump if equals.所以一旦它达到正确的case所有以下代码将被执行,甚至下一个case语句中的代码.您必须通过以编程方式停止switch块来处理此问题(您可以将其中断或返回).这就是fall-through重点.

你可以找到很多网站来解释它是如何switch case工作的.

现在你必须case用正确的实现填充每个- 它似乎是排列.

  • @RastaJedi,但如果默认情况不是最后一个,你确实需要它:) (2认同)
  • 是的,@ StoryTeller是对的; 最后一个案例是不一定需要"休息"的案例. (2认同)

Tom*_*e2k 6

这不是很清楚.但据我所知,教授提供了一个汇编代码和一个C代码
我认为他希望你以这种方式扩展C代码,编译它会产生类似于他提供的汇编代码.

我希望我没有弄乱它(我在阅读AT&T语法时遇到了重大问题),但对我来说这看起来像:

typedef enum {MODE_A, MODE_B, MODE_C, MODE_D, MODE_E} mode_t;
long switch3 (long *p1, long *p2, mode_t action) {
  long result = 0;
  switch(action){
    case MODE_A:  result = *p2; *p2 = *p1; break;
    case MODE_B:  result = *p2; *p1 = *p1 + *p2; break;
    case MODE_C:  result = *p2; *p1 = 59; break;
    case MODE_D: *p1 = *p2;  // fallthru to E
    case MODE_E: result = 27 break;
    default: result = 12;
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

"对于我来说,可能存在应该在C代码中写下来的情况",这是一个提示

    case MODE_D: *p1 = *p2;  // fallthru to E
    case MODE_E: result = 27 break;
Run Code Online (Sandbox Code Playgroud)

应该写,而不是

    case MODE_D: *p1 = *p2;  result = 27 break;
    case MODE_E: result = 27 break;
Run Code Online (Sandbox Code Playgroud)

(这会产生相同的结果)即使编译器为此选择了另一个标签

  • 啊好的,创建的代码总是100%代表它创建的代码?如果没有,那么我怀疑教程是否会落后... asm也不代表(不需要的)"结果"变量,它在asm中被优化,但存在于C-Code中.而不是断开开关,asm返回功能.另一个提示是编译器将"MODE_E"重新排列为第一种情况 (2认同)