【问题标题】:asm subroutine handling int and char from c++ fileasm 子例程处理来自 c++ 文件的 int 和 char
【发布时间】:2009-10-02 14:58:57
【问题描述】:

在与 c++ 程序链接后,如何在 asm 子例程中处理 int 和 char?例如extern "C" void LCD_ byte (char byte, int cmd_data); LCD_byte 如何处理“byte”和“cmd_data”?如何访问汇编代码中的“byte”和“cmd_data”?

【问题讨论】:

  • 请描述操作系统和架构。
  • 没有操作系统而且它正在运行 microblaze 架构

标签: c++ assembly char int


【解决方案1】:

这在很大程度上取决于您使用的微处理器。如果是x86,char会被加宽为int,然后两个参数都传到栈上。您可以通过将执行调用的 C 代码编译成汇编代码并检查汇编代码来发现自己。

例如,给定

void LCD_byte (char byte, int cmd_data);

void foo()
{
   LCD_byte('a',100);
}

gcc 在 x86 Linux 上生成代码

foo:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        movl    $100, 4(%esp)
        movl    $97, (%esp)
        call    LCD_byte
        leave
        ret

如您所见,两个值都被压入堆栈(因此“a”在顶部),然后对目标例程进行调用指令。因此,目标例程可以在esp+4处找到第一个传入的参数。

【讨论】:

    【解决方案2】:

    很大程度上取决于调用约定,而 AFAIK 又取决于编译器。

    但 99.9%% 的时间它是两件事之一。它们要么被传递到寄存器中,要么被压入堆栈并在函数内部弹出。

    【讨论】:

    • 可能有编译器特定的函数属性可用于选择调用约定。这些就像 fastcall、stdcall、regparm 等。
    【解决方案3】:

    查找适用于您平台的文档。它会告诉您 C 使用哪种调用约定。

    调用约定指定如何传递参数,哪些寄存器是调用者保存的,哪些是被调用者保存的,如何存储返回地址以及正确实现可以从 C 调用的函数所需的所有其他内容。(如以及正确调用 C 函数所需的一切)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-16
      • 2012-06-27
      相关资源
      最近更新 更多