【问题标题】:Call C function from Assembly code using as88 Assembler使用 as88 汇编器从汇编代码中调用 C 函数
【发布时间】:2011-09-04 01:54:47
【问题描述】:

我正在为 16 位处理器(特别是 8086/8088)开发浮点计算器。 我正在使用as88 Tracker,它没有实现浮点,不允许我将 sscanf 与“%f”一起使用。

我曾想过在 C 代码中执行此操作并从我的汇编代码中调用此函数,但不知道如何执行此操作。

这是我目前的代码:

#include "../syscalnr.h" .sect .文本 _代码_: 推bp mov bp, sp 推 SEGOP-PRIOP !将 PRIOP 字符串大小推入堆栈 推优先 推标准输出 推 _WRITE !系统调用以在显示器上打印字符串 系统 添加 sp, 8 mov di, rasc !准备 DI 接收 char 推 _GETCHAR 1:系统 cmpb al, '\n' !与 EOL 比较并继续存储字符串字符 杰2f 斯托布!将 char 存储到变量 rasc 跳转 1b 2:xorb al,al!清除寄存器 添加 sp, 2 .sect .数据 _数据_: PRIOP: .asciz "插入第一个操作数:\n" SEGOP: .ascii "插入第二个操作数:" 格式:.asciz "%u" F_CHAR: .asciz "%c" F_STR: .asciz "%s\n" .sect .bss _bss_: rasc:.space 10

我希望能够将 C 函数编写为:

float* getVal(char* ch) {

    float fVal;
    sscanf(ch, "%f", &fVal);

    if(fVal == 0) return 0;

    return fVal;
}

并从我的汇编代码中调用它,将用户输入的字符串数字转换为浮点数。

谁能帮我解决这个问题?

谢谢!

【问题讨论】:

  • 你要的函数好像是strtod,是标准库的一部分。
  • 好像我也可以使用那个,但回到重点,我怎样才能从我的汇编代码中调用这个函数?

标签: c assembly floating-point as88


【解决方案1】:

有一个 C 语言函数调用约定规定了在输入函数时需要如何设置寄存器。你必须找出那个约定是什么——也许通过查看一个 C 编译的 obj 文件——然后让你的 asm 代码遵守它,就像你在执行 sys 时所做的那样。不过,我认为这不是您唯一的问题,因为 sscanf() 无疑会调用 C 库中的大量其他函数,然后您需要找到这些函数;并理解;并整合;和调试;不断地。忘掉那个噪音吧。

Unsolicited-advice alert: 直接在你的 asm 代码中解析输入可能会更容易——如果我这样做会更容易。如果这个人输入“3.14159”,那很容易,不是吗?即使您看到的是科学记数法输入,这也不算太糟糕,imo。

【讨论】:

  • 取决于您想要或需要的正确程度。即使在高级语言中,解析浮点而不出现舍入错误也是一项艰巨的任务。我会非常害怕在 asm 中尝试它。
  • 这取决于。我需要 IEEE 754-2008 标准中的浮点数。因此,如果我有一个字符串“3.14159”,我该如何解析它,以便我可以有一个标准化的二进制准备好为符号、指数和分数“屏蔽”,然后正确极化以进行后验计算?简而言之:我需要一个符合 IEEE 754-2008 标准的二进制文件,以便在计算中使用它。如何将我的字符串“3.14159”转换为浮点数 3.14159?
  • 我不明白你的问题。您有这个恰好代表浮点数的字符串:“3.14159”。您必须将其解析为整数部分和小数部分,然后将该傻瓜转换为四字节的 IEEE-754 二进制文件。当然,这不是微不足道的,但它看起来很简单,除了您了解 IEEE-754 的要求。那么我没有得到您问题的哪一部分?
  • 问题是我的 Assembler (as88) 没有实现浮点数,所以我需要调用一个外部 C 函数或 C 程序,它只会选择这个字符串并返回一个浮点数,所以我可以使用它在我的汇编代码中。
【解决方案2】:

首先,这只有在您的 C 库也在模拟器上运行时才有效。 我不知道您的 8088 仿真器与 x86 ABI 到底有多接近,但假设它在过去 20 年中没有太大变化(咳咳),您可以像这样从汇编程序中调用 C 函数:

    push    RETVAL    ;last parameter first (address of float to return)
    push    STRFLOAT  ;first parameter last (format string)
    call    sscanf    ;error code is in ax
    add     sp,4      ;returned float is at RETVAL
    ;do something...

.sect .data
    STRFLOAT: .asciz  "%f"

.sect .bss
    RETVAL:   .space 4

根据名称修改,您可能需要将 sscanf 替换为 _sscanf 或 sscanf_。

【讨论】:

    猜你喜欢
    • 2016-06-01
    • 2016-09-07
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 2016-08-27
    • 2013-03-13
    • 2018-10-13
    相关资源
    最近更新 更多