现在编写一个简单的应用程序,提示用户输入整数,通过移位的方式将其与 2 的幕 (2¹〜2ⁿ) 相乘,并用填充前导空格的形式再次显示每个乘积。输入-输出使用 c++。汇编模块将调用 3 个 c++ 编写的函数。程序将由 c++ 模块启动。
汇编语言模块
汇编模块包含一个函数 displaytable。它调用 c++ 函数 askforinteger 从用户输入一个整数。它还使用循环结构把整数 intval 重复左移,并调用 showint 进行显示。
; c++ 调用asm函数.include irvine32.inc;外部c++函数askforinteger proto cshowint proto c, value:sdword, outwidth:dwordout_width = 8ending_power = 10.dataintval dword ?.code;---------------------------------------------settextoutcolor proc c, color:dword;; 设置文本颜色,并清除控制台窗口; 调用 irvine32 库函数;--------------------------------------------- mov eax,color call settextcolor call clrscr retsettextoutcolor 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 retdisplaytable endpend
在 displaytable 过程中,必须在调用 showint 和 newline 之前将 ecx 入栈,并在调用后将 ecx 出栈,这是因为 visual c++ 函数不会保存和恢复通用寄存器。函数 askforinteger 用 eax 寄存器返回结果。
displaytable 在调用 c++ 函数时不一定要用 invoke。push 和 call 指令也能得到同样的结果。对 showint 的调用如下所示:
push out_width ;最后一个参数首先入栈push intvalcall showint ;调用函数add esp,8 ;清除堆栈
必须遵守 c 语言调用规范,其参数按照逆序入栈,且主调方负责在调用后从堆栈移除实参。
c++ 测试程序
下面查看启动程序的 c++ 模块。其入口为 main(),保证执行所需 c++ 语言的初始化代码。它包含了外部汇编过程和三个输岀函数的原型:
// main.cpp// 演示c++程序和外部汇编模块的函数调用#include #include 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 n; return n;}// 按特定宽度显示一个有符号整数void showint( int value, int width ){ cout << setw(width) << value;}
生成项目
将 c++ 和汇编模块添加到 visual studio 项目,并在 project 菜单中选择 build solution。
程序输出
当用户输入为 90 000 时,乘法表程序产生的输出如下:
visual studio 项目属性
如果使用 visual studio 生成集成了 c++ 和汇编代码的程序,并且调用 irvine32 链接库,就需要修改某些项目设置。以 multiplication_table 程序为例。
在 project 菜单中选择 properties,在窗口左边的 configuration properties 条目下,选择 linker。在右边面板的 additional library directories 条目中输入 c:irvine。
示例如下图所示。点击ok关闭 project property pages 窗口。现在 visual studio 就可以找到 irvine32 链接库了。
【回顾往年CES】酷派登上纽约时代广场大屏幕,斩获IDG三项大奖
数据分析时如何搞定深度分析?
教大家如何使用示波器调试电源固件
物联网正在进一步推动各大新兴场景的加速崛起
只要完成这两步 激光电视品牌就可以实现进阶目的
汇编语言模块调用C++函数实例
手机侧键手感测试机的分析?|深圳磐石测控
电力变压器的状态维修
国内首起利用区块链、以数字货币为交易媒介的特大跨国网络传销犯罪案
上海15岁女生发明可捡乒乓球的机器人
关于Arm服务器芯片的性能分析和应用
医疗放射在线监测系统的应用价值
介绍激光雷达和相机在无人车感知中的应用
中兴通讯采用‘乐高’积木模块化组合模式,提供精准云网等平台
什么是证明度量,如何帮助向平台证明正在运行的固件
抢占席位|2023英飞凌宽禁带应用技术发展论坛
微软康容:做无障碍领域的创新者与实践者,让我们的世界更包容
苹果A17芯片规格曝光 a16芯片和a17对比
小米AI移动端深度学习框架MACE开源了!
ROS与移动底盘的通信试验内容