▶ 书中第十三章的程序,主要讲了汇编语言和 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. 查看耗时长,CPU 100% 的SQL

    [session_id], [request_id], [start_time] AS '开始时间', [status] AS '状态', [command] AS '命令', dest.[text] ...

  2. js写法【3】

    var m=[]; m[m.length]=xx;//相当于push 对Repeat方法提供了8种写法做比较,这一点还是不错的.

  3. Xshell5 评估过期,需要采购,不能使用

    Xshell5 评估过期,需要采购,不能使用 标签: Xshell linux 2017年10月10日 13:13:1029507人阅读 评论(9) 收藏 举报 版权声明:本文为博主原创文章,未经博主 ...

  4. vue中绑定多个class,多个情况使用同一个class时,用js的或 “||”

    class中 当依赖中断的时候是绑定的red,但是这样写绑定不了, 大括号{}里可以下js代码的,下面的orange就可以绑定成功,写成双竖线 形式.

  5. java高并发编程(四)高并发的一些容器

    摘抄自马士兵java并发视频课程: 一.需求背景: 有N张火车票,每张票都有一个编号,同时有10个窗口对外售票, 请写一个模拟程序. 分析下面的程序可能会产生哪些问题?重复销售?超量销售? /** * ...

  6. Web jsp开发学习——实现页面跳转和传参

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExcepti ...

  7. 面试总结之PYTHON

    source code https://github.com/haoran119/interview/tree/master/interview%20summary%20of%20python [ZZ ...

  8. centos6.5kvm虚拟化技术

    KVM的安装 一.KVM环境配置 1.修改内核模式为兼容内核启动 查看系统内核信息 # uname -a # vi /boot/grub/grub.conf 2.关闭selinux,重启后生效 # v ...

  9. SwipeRefreshLayout 和RecyclerView 使用

    使用是布局 <android.support.v4.widget.SwipeRefreshLayout android:id="@id/id_swiperefreshlayout&qu ...

  10. BBC曝光:每天10000步,竟是商家的营销骗局

    原文: https://new.qq.com/cmsn/20190112A14JRD00 导语:日本人平均每天行走3500-5000步,于是计步器公司就想,既然这么个数值大部分人都能达到,如果把平均值 ...