【问题标题】:Function Calls and Assembly [closed]函数调用和汇编[关闭]
【发布时间】:2014-09-30 19:56:31
【问题描述】:

我试图了解程序如何使用汇编 x86 代码进行函数调用(使用 C 语义)。任何帮助将不胜感激。

我找不到任何资料来专门回答这个问题。

【问题讨论】:

  • 到目前为止,理解这一点最简单的方法是编写一个 C 程序并使用您喜欢的编译器编译它,并选择生成输出列表,或者 - 失败 - 通过在调试器。
  • 任何对您有用的答案都取决于您所针对的 ABI。您正在使用什么机器/环境/工具链?
  • 你想了解一些调用约定吗?
  • Google 的“汇编 x86 代码函数调用”点击数以千计 - 第一个非常好。

标签: c assembly call function-calls function-call


【解决方案1】:

在 x86 中,有名为 callret 的指令来执行此操作。 call 将当前地址存储在堆栈中,并将 jmp 存储到作为参数传递的标签中。而名为ret 的指令则弹出该地址并在该地址添加一个字节后跳转到该地址。

代码示例:

C

int sum(int a, int b)
{
  return a + b;
}

void f(void)
{
  sum(2, 2);
  g();
}

编译器可能会生成(x86-assembly-like example):

f:
  push 2
  push 2
  call sum
  call g
  ret

sum:
   pop eax
   pop ebx
   add eax, ebx
   ret

希望对你有帮助

【讨论】:

    【解决方案2】:

    过去,我很幸运地使用了以下资源。

    如果您正在寻找如何将函数调用转换为程序集,请在上面的链接中查找 __cdecl 调用约定。基本上,不同的调用约定指定了不同的(并不总是标准化的)通过操作堆栈来传递参数的方式,__cdecl 只是其中一种方式——“C”调用约定。

    如果您想知道如何从汇编代码中调用 C 函数,最后两个链接非常好。

    我可以给出的另一个建议是,如果您有一个要从 C 调用的汇编函数,请在 C 中的函数声明中指定调用约定。例如,我曾经在 @987654328 之后编写汇编代码@调用约定而不是__cdecl,所以在函数签名中我明确指定了__stdcall约定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-06
      • 2012-12-03
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      相关资源
      最近更新 更多