• 汇编语言调用C语言/C++实例:乘法表

    现在编写一个简单的应用程序,提示用户输入整数,通过移位的方式将其与 2 的幕 (2¹〜2ⁿ) 相乘,并用填充前导空格的形式再次显示每个乘积。输入-输出使用 C++。汇编模块将调用 3 个 C++ 编写的函数。程序将由 C++ 模块启动。

    汇编语言模块

    汇编模块包含一个函数 DisplayTable。它调用 C++ 函数 askForInteger 从用户输入一个整数。它还使用循环结构把整数 intVal 重复左移,并调用 showInt 进行显示。

    ; C++ 调用ASM函数.
    
    INCLUDE Irvine32.inc
    
    ;外部C++函数
    askForInteger PROTO C
    showInt PROTO C, value:SDWORD, outWidth:DWORD
    
    OUT_WIDTH = 8
    ENDING_POWER = 10
    
    .data
    intVal DWORD ?
    
    .code
    ;---------------------------------------------
    SetTextOutColor PROC C,
        color:DWORD
    ;
    ; 设置文本颜色,并清除控制台窗口
    ; 调用 Irvine32 库函数
    ;---------------------------------------------
        mov    eax,color
        call    SetTextColor
        call    Clrscr
        ret
    SetTextOutColor ENDP
    
    ;---------------------------------------------
    DisplayTable PROC C
    ;
    ; 输入一个整数 n 并显示范围为 n * 2^1 ~ n * 2^10的乘法表
    ;----------------------------------------------
        INVOKE askForInteger                 ; 调用 C++ 函数
        mov    intVal,eax                    ; 保存整数
        mov    ecx,ENDING_POWER              ; 循环计数器
    
    L1:    push ecx                          ; 保存循环计数器
        shl  intVal,1                        ; 乘以 2
        INVOKE showInt,intVal,OUT_WIDTH
        call    Crlf
        pop    ecx                           ; 恢复循环计数器
        loop    L1
    
        ret
    DisplayTable ENDP
    
    END

    在 DisplayTable 过程中,必须在调用 showInt 和 newLine 之前将 ECX 入栈,并在调用后将 ECX 出栈,这是因为 Visual C++ 函数不会保存和恢复通用寄存器。函数 askForInteger 用 EAX 寄存器返回结果。

    DisplayTable 在调用 C++ 函数时不一定要用 INVOKE。PUSH 和 CALL 指令也能得到同样的结果。对 showInt 的调用如下所示:

    push OUT_WIDTH  ;最后一个参数首先入栈
    push intVal
    call showInt             ;调用函数
    add esp,8                ;清除堆栈

    必须遵守 C 语言调用规范,其参数按照逆序入栈,且主调方负责在调用后从堆栈移除实参。

    C++ 测试程序

    下面查看启动程序的 C++ 模块。其入口为 main(),保证执行所需 C++ 语言的初始化代码。它包含了外部汇编过程和三个输岀函数的原型:

    // main.cpp
    
    // 演示C++程序和外部汇编模块的函数调用
    
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    extern "C" {
        // 外部 ASM 过程:
        void DisplayTable();
        void SetTextOutColor( unsigned color );
    
        // 局部 C++ 函数:
        int askForInteger();
        void showInt( int value, int width );
    }
    
    // 程序入口
    int main()
    {
        SetTextOutColor( 0x1E );       // 蓝底黄字
        DisplayTable();                // 调用 ASM 过程
        return 0;
    }
    
    // 提示用户输入一个整数
    
    int askForInteger()
    {
        int n;
        cout << "Enter an integer between 1 and 90,000: ";
        cin >> n;
        return n;
    }
    
    // 按特定宽度显示一个有符号整数
    
    void showInt( int value, int width )
    {
        cout << setw(width) << value;
    }

    生成项目

    将 C++ 和汇编模块添加到 Visual Studio 项目,并在 Project 菜单中选择 Build Solution。

    程序输出

    当用户输入为 90 000 时,乘法表程序产生的输出如下:

更多...

加载中...