现在编写一个简短的程序,清除屏幕,显示当前磁盘目录,并请求用户输入文件名。程序员可能希望扩展该程序,以打开并显示被选中文件。6 y* g( o4 B) m, Q. O5 h# D/ X
一、C++ 根模块
& e, n/ g, H3 P8 T* Y" h C++ 模块只有一个对 asm_main 的调用,因此可以将其称为根模块 (stub module):
& h( n9 m* L9 d8 K$ M" H// main.cpp
//根模块:启动汇编程序
extern "C" void asm_main() ; // asm 启动过程
void main()
{
asm_main();
} 二、ASM 模块& x/ x; p) M: a( D% ~% r. I( ?
汇编语言模块包括了函数原型、若干字符串和一个 fileName 变量。模块两次调用 system 函数,向其传递“cls”和“dir”命令。然后调用 printf,显示请求文件名的提示行,再调用 scanf,使用户输入文件名。$ M5 J! w8 f! O9 e' y8 [5 }
程序不调用 Irvine32 库中的任何函数,因此可以将 .MODEL 伪指令设置为 C 语言规范:
* h/ N% N0 m3 C/ h; n/ C! c5 g! L; 从 C++ 启动的 ASM 程序 (asmMain.asm)
.586
.MODEL flat,C
; 标准 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 = 5000
.data
str1 BYTE "cls",0
str2 BYTE "dir/w",0
str3 BYTE "Enter the name of a file: ",0
str4 BYTE "%s",0
str5 BYTE "cannot open file",0dh,0ah,0
str6 BYTE "The file has been opened and closed",0dh,0ah,0
modeStr BYTE "r",0
fileName BYTE 60 DUP(0)
pBuf DWORD ?
pFile DWORD ?
.code
asm_main PROC
; 清除屏幕,显示磁盘目录
INVOKE system,ADDR str1
INVOKE system,ADDR str2
; 清除文件名
INVOKE printf,ADDR str3
INVOKE scanf, ADDR str4, ADDR fileName
; 尝试打开文件
INVOKE fopen, ADDR fileName, ADDR modeStr
mov pFile,eax
.IF eax == 0 ; 不能打开文件
INVOKE printf,ADDR str5
jmp quit
.ELSE
INVOKE printf,ADDR str6
.ENDIF
; 关闭文件
INVOKE fclose, pFile
quit:
ret ; 返回 C++ 主程序
asm_main ENDP
END 函数 scanf 需要两个参数:第一个是格式化字符串(“%s”)的指针,第二个是输入字符串变量(fileName)的指针。因为互联网上有丰富的文档,因此这里不再浪费时间来解释标准 C 函数。 |