▶ 书中第十三章的程序,主要讲了汇编语言和 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. SpringMVC-DispatcherServlet配置(Spring-servlet.xml)

    Spring-servlet.xml <context:component-scan base-package="com.spring.mvc.controller"/> ...

  2. [Android] Surface、SurfaceHolder与SurfaceView

    其实相当于MVC结构的三者关系:M(Surface).V(SurfaceView).C(SurfaceHolder) 1.Surface Handle onto a raw buffer that i ...

  3. 关于java中Static关键字的加强理解

    static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键字的用法和平常容易误解的地方,最后列 ...

  4. 将Word,PDF文档转化为图片

    #region 将Word文档转化为图片 /// <summary> /// 将Word文档转化为图片 /// </summary> /// <param name=&q ...

  5. 天朝屁民每天做T跟菜贩一样,进菜-卖菜,为伟大的菜贩精神点赞

    天朝屁民每天做T跟菜贩一样,进菜-卖菜,为伟大的菜贩精神点赞

  6. C#修改类模板

    安装目录下 Program Files\vs2013\Common7\IDE\ItemTemplatesCache\CSharp\Code\2052\Class 注意:中文是2052 英文是1033 ...

  7. HEAD插件安装

    简介 是一个HTML5编写的集群操作和管理工具,可以对集群进行傻瓜式操作,Head插件中可以显示集群的拓扑结构,执行索引和节点级别等操作,同时也可以输入RESTful命令和Elasticsearch交 ...

  8. bundle adjustment原理(1)

    那些光束平差的工具,比如SBA.SSBA之类的虽然好,然而例子和教程都不够多且不够详细,让初学者难以上手. 要传入的参数虽然有解释,然而却也不是十分清楚其含义,具体要怎么生成,生成为什么形式. 我在折 ...

  9. checked和stop()的讲解

    input:cheacked (属性选择器): checked 选中复选框 $("p").stop(ture); 代码的翻译:(参数)布尔值  p身上所有的动画都停止了 加不加tr ...

  10. JVM -verbose参数详解(转)

    原文 http://www.javaranger.com/archives/367 java -verbose[:class|gc|jni] 在输出设备上显示虚拟机运行信息. java -verbos ...