▶ 书中第十三章的程序,主要讲了汇编语言和 C/++ 相互调用的方法

● 代码,汇编中调用 C++ 函数

 ; subr.asm
INCLUDE Irvine32.inc askForInteger PROTO C
showInt PROTO C, value:SDWORD, outWidth:DWORD OUTPUT_WIDTH =
MAX_POWER = .data
intVal DWORD ? .code
SetTextOutColor PROC C, color:DWORD
mov eax, color
call SetTextColor
call Clrscr
ret
SetTextOutColor ENDP DisplayTable PROC C
INVOKE askForInteger ; 调用 C++ 函数输入整数
mov intVal, eax ; 保存返回值
mov ecx, MAX_POWER L1:
push ecx
shl intVal, ; 每次乘以 2
INVOKE showInt, intVal, OUTPUT_WIDTH ; 调用 C++ 函数显示结果
call Crlf
pop ecx
loop L1 ret
DisplayTable ENDP END
 // main.cpp
#include <iostream>
#include <iomanip>
using namespace std; extern "C" // 声明外部 asm 过程和 C++ 函数
{
void SetTextOutColor(unsigned color); // 设置终端字体和背景颜色
void DisplayTable(); // 显示表格 int askForInteger(); // 输入整数
void showInt(int value, int width); // 按宽度 width 显示数字 value
} int main()
{
SetTextOutColor(0x1E); // 蓝底黄字
DisplayTable(); getchar();
getchar();
return ;
} int askForInteger()
{
int n;
cout << "Target integer [1, 90000]: ";
cin >> n;
return n;
} void showInt(int value, int width)
{
cout << setw(width) << value;
}

■ 输出结果

● 代码,汇编调用 C/C++ 库函数和自定义函数。有个奇怪的 bug,scanf 至少要在主函数中用一次,否则汇编的目标文件找不到,暂时不明。

 ; asmMain.asm
INCLUDE Irvine32.inc printSingle PROTO C, aSingle:REAL4, precision:DWORD ; 声明外部函数(库函数不用声明) TAB = .code
asmMain PROC C ; 程序入口 .data ; 测试 printf
format BYTE "%.2f",TAB,"%.3f",0dh,0ah,
val1 REAL8 .
val2 REAL8 .
.code
INVOKE printf, ADDR format, val1, val2 ; 调用 printf
; 书本注释曰,不能用 INVOKE ptrintf 来显示 REAL4 型变量? .data ; 测试 scanf
strSingle BYTE "%f",
strDouble BYTE "%lf",
float1 REAL4 .
double1 REAL8 . .code
INVOKE scanf, ADDR strSingle, ADDR float1 ; 调用 scanf,覆盖掉原本的值
INVOKE scanf, ADDR strDouble, ADDR double1 .data ; 测试栈传参 printf 和自定义函数
valStr BYTE "float1 in ASM = %.3f", 0dh, 0ah, .code
fld float1 ; 将 float1 转存到 FPU 栈中
sub esp, ; 指到栈的高位
fstp qword ptr [esp] ; 当成 double 取出
push OFFSET valStr ; 栈传参来调用 printf
call printf
add esp,
INVOKE printSingle, float1, ; 自定义外部函数来显示 float1 call Crlf
ret
asmMain ENDP END
 // main.cpp
#define _CRT_SECURE_NO_WARNINGS // 关闭 MVC++ 关于 scanf 被 scanf_s 取代的警告 #include <stdio.h>
#include <string>
#include <strstream> using namespace std; extern "C"
{
void asmMain();
void printSingle(float d, int precision);
} void printSingle(float d, int precision)
{
strstream temp;
temp << "float1 in C++ = %." << precision << "f" << '\0';
printf(temp.str(), d);
} int main()
{
asmMain();
scanf(""); // 如果没有这一句就会报错:LNK2019,无法解析的外部符号 _scanf,该符号在函数 _asmMain 中被引用
getchar();
getchar();
return ;
}

■ 程序输出

456.79  864.231
123.456
123456789.123456789

float1 in ASM = 123.456
float1 in C++ = 123.456

● 代码,汇编调用 C 库函数,system 和 file 相关。还是有那个要在主函数里用一次 printf 和 scanf 的问题。

 ; asmMain.asm
.
.MODEL flat, C system PROTO, pCommand:PTR BYTE ; 声明一堆库函数
printf PROTO, pString:PTR BYTE, args:VARARG
scanf PROTO, pFormat:PTR BYTE,pBuffer:PTR BYTE, args:VARARG
fopen PROTO, mode:PTR BYTE, filename:PTR BYTE
fclose PROTO, pFile:DWORD BUFFER_SIZE =
.data
str1 BYTE "cls",
str2 BYTE "dir/w",
str3 BYTE "Enter the name of a file: ",
str4 BYTE "%s",
str5 BYTE "Failed to open the file", 0dh, 0ah,
str6 BYTE "Succeeded to open the file", 0dh, 0ah,
modeStr BYTE "r", fileName BYTE DUP()
pBuf DWORD ?
pFile DWORD ? .code
asm_main PROC
INVOKE system,ADDR str1 ; cls
INVOKE system,ADDR str2 ; dir INVOKE printf,ADDR str3 ; 提示信息
INVOKE scanf, ADDR str4, ADDR fileName ; 输入文件名 INVOKE fopen, ADDR fileName, ADDR modeStr ; 尝试打开文件
mov pFile, eax .IF eax ==
INVOKE printf,ADDR str5
jmp quit
.ELSE
INVOKE printf,ADDR str6
.ENDIF
INVOKE fclose, pFile quit:
ret
asm_main ENDP
END
 // main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> extern "C" void asm_main(); void main()
{
asm_main();
scanf("");
printf("");
getchar();
getchar();
}

《汇编语言 基于x86处理器》第十三章高级语言接口部分的代码 part 2的更多相关文章

  1. 《汇编语言 基于x86处理器》第九章字符串与数组部分的代码

    ▶ 书中第九章的程序,主要讲了字符串相关的输入.输出,以及冒泡排序.二分搜索 ● 代码,Irvine32 中的字符串库函数代码范例 INCLUDE Irvine32.inc .data str1 BY ...

  2. 《汇编语言 基于x86处理器》第八章高级过程部分的代码 - 两种规范计算数组元素的和

    ▶ 输入 Count 个 32 位有符号整数,计算他们的和 ● 代码,使用堆栈传参 ;// Sum_main.asm,主过程 INCLUDE Irvine32.inc EXTERN PromptFor ...

  3. 《汇编语言 基于x86处理器》第十一章 MS-DOS 编程部分的代码 part 2

    ▶ 书中第十一章的程序,主要讲了 Windows 接口,在小黑框中进行程序交互 ● 在屏幕指定位置输出带自定义属性的文字 INCLUDE Irvine32.inc .data outHandle HA ...

  4. 《汇编语言 基于x86处理器》第十二章浮点数部分的代码

    ▶ 书中第十二章的程序,主要讲了 FPU 的指令和浮点数计算的过程 ● 代码,简单的 32 为浮点数测试 INCLUDE Irvine32.inc INCLUDE macros.inc .data f ...

  5. 《汇编语言 基于x86处理器》第七章整数运算部分的代码

    ▶ 书中第七章的程序,使用各种位移运算,加深了对内存.寄存器中整数类型变量存储的认识 ● 代码,双字数组右移 4 位 INCLUDE Irvine32.inc COUNT = ; 右移位数 .data ...

  6. 《汇编语言 基于x86处理器》第六章条件处理部分的代码

    ▶ 书中第六章的程序,使用了条件判断和跳转来实现一些功能 ● 代码,查找数组首个非零值 INCLUDE Irvine32.inc .data intArray SWORD , , , , , , , ...

  7. 《汇编语言 基于x86处理器》前五章的小程序

    ▶ 书中前五章的几个小程序,基本的运算操作,使用了作者的库 Irvine32 和 Irvine64(一开始以为作者网站过期了,各网站上找到的文件大小都不一样,最后发现是要搭梯子 Orz,顺利下载).注 ...

  8. 《汇编语言 基于x86处理器》第十章 - 运行一个 16位实地址汇编程序

    ▶ 书上第 10 章,主要讲了宏,引用了一个 16 位实地址的程序,从代码开始到运行 ● 代码 ; main.asm INCLUDE Macros.inc IF IsDefined( RealMode ...

  9. 《汇编语言 基于x86处理器》第十章结构和宏部分的代码

    ▶ 书中第十章的程序,主要讲了结构与宏的使用 ● 代码,使用结构,对比是否对齐的性能差距 INCLUDE Irvine32.inc INCLUDE macros.inc structN STRUCT ...

随机推荐

  1. Delphi常用API,API函数

    auxGetDevCaps API 获取附属设备容量 auxGetNumDevs API 返回附属设备数量 auxGetVolume API 获取当前卷设置 auxOutMessage API 向输出 ...

  2. oracle中delete、truncate、drop的区别

    oracle中delete.truncate.drop的区别 标签: deleteoracletable存储 2012-05-23 15:12 7674人阅读 评论(0) 收藏 举报  分类: ora ...

  3. NPOI将DataGridView中的数据导出+导出Chart图表图片至Excel

    #region 导出Excel private HSSFWorkbook Workbook = null; private Sheet SheetOne = null; private DataFor ...

  4. HTTP请求报文

    一个HTTP请求报文,有请求行request line.请求头部header.空行和请求数据组成.看下图可知: 1.请求行 请求行:请求方法.请求地址和协议版本. 请求方法 HTTP/1.1 定义的请 ...

  5. Java-Runoob-高级教程-实例-数组:11. Java 实例 – 删除数组元素

    ylbtech-Java-Runoob-高级教程-实例-数组:11. Java 实例 – 删除数组元素 1.返回顶部 1. Java 实例 - 删除数组元素  Java 实例 以下实例演示了如何使用 ...

  6. Oracle 表空间的概念

    表空间   在数据库系统中,存储空间是较为重要的资源,合理利用空间,不但能节省空间,还可以提高系统的效率和工作性能. Oracle 可以存放海量数据,所有数据都在数据文件中存储.而数据文件大小受操作系 ...

  7. docker镜像创建redis5.0.3容器集群

    拉取redis5.0.3镜像 # docker pull daocloud.io/library/redis:5.0.3 [root@localhost ~]# docker pull daoclou ...

  8. 二进制编译安装httpd服务

    systemctl stop httpd yum remove httpd-----------------------(在做之前 先删掉httpd) 安装编译环境 yum -y groupinsta ...

  9. 电脑不能上网win7 解决办法

    情况一览: 电脑连的是WIFI 手机能上,局域网其他电脑能上 电脑浏览器打不开网页 问题解决: //win+R 快捷键进入cmd 1.ipconfig 看电脑有没有ip 2.ipconfig nslo ...

  10. UE4如何检测目标在锥形视野内

    转自:http://blog.csdn.net/l346242498/article/details/70237083 做UE4游戏AI方面经常会遇到一个问题,就是何如判定目标在AI单位的视野范围内, ...