• 汇编语言调用C语言/C++库函数

    C 语言有标准函数集合,被称为标准 C 库 (Standard C Library)。同样的函数还可以用于 C++ 程序,因此,也可用于与 C 和 C++ 程序连接的汇编模块。

    汇编模块调用 C 函数时,就必须包含函数的原型。一般通过访问 C++ 编译器的帮助系统可以找到 C 函数原型。程序调用 C 函数时,需要先将 C 函数原型转换为汇编语言原型。

    printf 函数

    下面是 printf 函数的 C/C++ 语言原型,第一个参数为字符指针,其后跟了一组可变数量的参数:

    int printf(
        const char * format [, argument]...
    );

    C/C++ 编译器的帮助库可以查阅到 printf 函数文档。汇编语言中与之等效的函数原型将 char* 改为 PTR BYTE,将可变长度参数列表的类型改为 VARARG:

    printf PROTO C, pString:PTR BYTE, args:VARARG

    另一个有用的函数是 scanf,用于从标准输入(键盘)接收字符、数字和字符串,并将输入数值分配给变量:

    scanf PROTO C, format:PTR BYTE, args:VARARG

    用 printf 函数显示格式化实数

    编写汇编函数格式化并显示浮点数不是一件容易的事。与其由程序员自行编码,还不如利用 C 库的 printf 函数。需要创建 C 或 C++ 的启动模块,并将其与汇编代码链接。

    下面给出了用 Visual C++.NET 创建这种程序的过程:

    1) 用 Visual C++ 创建一个 Win32 控制台程序。创建文件 main.cpp,并插入函数 main,该函数调用了 asmMain:

    extern "C" void asmMain();
    int main()
    {
        asmMain();
        return 0;
    }

    2) 在 main.cpp 所在的文件夹中,创建一个汇编模块 asmMain.asm。该模块包含过程 asmMain,并声明使用 C 调用规范:

    ; asmMain.asm
    .386
    .model flat,stdcall
    .stack 2000
    .code
    asmMain PROC C
        ret
    asmMain ENDP
    END

    3) 汇编 asmMain.asm(但不进行链接),生成 asmMain.obj。

    4) 将 asmMain.obj 添加到 C++ 项目。

    5) 构建并运行项目。如果修改了 asmMain.asm,则在运行前,需要再一次汇编和构建项目。

    一旦程序正确建立,就可以向 asmMain.asm 添加代码来调用 C/C++ 函数。

    显示双精度数值
    下面是 asmMain 中的汇编代码,它通过调用 printf 输岀了一个类型为 REAL8 的数值:

    .data
    double1 REAL8 1234567.890123
    formatStr BYTE "%.3f", 0dh, 0ah, 0
    .code
    INVOKE printf, ADDR formatStr, double1

    相应的输出如下:

    1234567.890

    这里,传递给 printf 的格式化字符串与 C++ 中的略有不同:不是插入转义字符,如 \n,而是必须插入 ASCII 字符(0dh, 0ah)。

    传递给 printf 的浮点参数应声明为 REAL8 类型。不过传递的数值也可能是 REAL4 类型,这需要相当的编程技巧。若想了解 C++ 编译器是如何工作的,可以声明一个 float 类型的变量,并将其传递给 printf。编译程序,并用调试器跟踪该程序的反汇编代码。

    多参数

    printf 函数接收可变数量的参数,因此很容易在一次函数调用中对两个数进行格式化并显示它们:

    TAB = 9
    .data
    formatTwo BYTE "%.2f",TAB,"%.3f",0dh,0ah,0
    val1 REAL8 456.789
    val2 REAL8 864.231
    .code
    INVOKE printf, ADDR formatTwo, val1, val2

    相应的输岀如下:

    456.79   864.231

    用 scanf 函数输入实数

    调用 scanf 可以从用户输入浮点数。SmallWin.inc(包括在 Irvine32.inc 内)定义的函数原型如下所示:

    scanf PROTO C,
        format:PTR BYTE, args:VARARG

    传递给它的参数包括:格式化字符串的偏移量,一个或多个 REAL4、REAL8 类型变量的偏移量(这些变量存放了用户输入的数值)。调用示例如下:

    .data
    strSingle BYTE "%f", 0
    strDouble BYTE "%lf",0
    single1 REAL4 ?
    double1 REAL8 ?
    .code
    INVOKE scanf, ADDR strSingle, ADDR single1
    INVOKE scanf, ADDR strDouble, ADDR double1

    必须从 C 或 C++ 启动程序中调用汇编语言代码。

更多...

加载中...