本节主要讲解使用传统的 EXTERN 伪指令引用位于不同模块中的函数。
jprompt.asm 是 PromptForIntegers 过程的源代码文件。它显示提示要求用户输入三个整数,调用 Readlnt 获取数值,并将它们插入数组:
- ;提示整数输入请求 (_prompt.asm)
- INCLUDE Irvine32.inc
- .code
- ;--------------------------------
- PromptForIntegers PROC
- ;提示用户为数组输入整数,并用
- ;用户输入填充该数组。
- ;接收:
- ; ptrPrompt:PTR BYTE ;提示信息字符串
- ; ptrArray:PTR DWORD ;数组指针
- ; arraySize:DWORD ;数组大小
- ;返回:无
- ;--------------------------------
- arraySize EQU [ebp+16]
- ptrArray EQU [ebp+12]
- ptrPrompt EQU [ebp+8]
- enter 0,0
- pushad ;保存全部寄存器
- mov ecx,arraySize
- cmp ecx,0 ;数据大小WO?
- jle L2 ;是:退出
- mov edx,ptrPrompt ;提示信息的地址
- mov esi,ptrArray
- L1: call WriteString ;显示字符串
- call ReadInt ;将整数读入EAX
- call Crlf ;换行
- mov [esi],eax ;保存入数组
- add esi,4 ;下一个整数
- loop L1
- L2: popad ;恢复全部寄存器
- leave
- ret 12 ;恢复堆栈
- PromptForIntegers ENDP
- END
_arraysum.asm 模块为 ArraySum 过程,计算数组元素之和,并用 EAX 返回计算结果:
- ;ArraySumit程 (_arrysum.asm)
- INCLUDE Irvine32.inc
- .code
- ;----------------------------------------------
- ArraySum PROC
- ;计算32位整数数组之和。
- ;接收:
- ; ptrArray ;数组指针
- ; arraySize ;数组大小(DWROD)
- ;返回:EAX = 和数
- ;----------------------------------------------
- ptrArray EQU [ebp+8]
- arraySize EQU [ebp+12]
- enter 0,0
- push ecx ;EAX 不入栈
- push esi
-
- mov eax, 0 ;和数清零
- mov esi, ptrArray
- mov ecx,arraySize
- cmp ecx, 0 ;数组大小WO?
- jle L2 ;是:退出
- L1: add eax, [esi] ;将每个整数加到和数中
- add esi,4 ;指向下一个整数
- loop L1 ;按数组大小重复
- L2: pop esi
- pop ecx ;用EAX返回和数
- leave
- ret 8 ;恢复堆栈
- ArraySum ENDP
- END
_display.asm 模块为 DisplaySum 过程,显示标号和和数的结果:
- ;DisplaySum 过程 (_display.asm)
- INCLUDE Irvine32.inc
- .code
- ;-----------------------------------------
- DisplaySum PROC
- ;在控制台显示和数。
- ;接收:
- ; ptrPrompt ;提示字符串的偏移量
- ; theSum ;数组和数(DWROD)
- ;返回:无
- ;-----------------------------------------
- theSum EQU [ebp+12]
- ptrPrompt EQU [ebp+8]
- enter 0,0
- push eax
- push edx
- mov edx,ptrPrompt ;提示字符串的指针
- call WriteString
- mov eax,theSum
- call Writelnt ;显示 EAX
- call Crlf
- pop edx
- pop eax
- leave
- ret 8 ;恢复堆栈
- DisplaySum ENDP
- END
Sum_main.asm 模块为启动过程 (main)。其中的 EXTERN 伪指令指定了三个外部过程。为了使源代码更加友好,用 EQU 伪指令再次定义了过程名:
每次过程调用之前,用注释说明了参数顺序。该过程使用 STDCALL 参数传递规范:
- ;整数求和过程(Sum_main.asm)
- ;多模块示例
- ;本程序由用户输入多个整数,
- ;将它们存入数组,计算数组之和,
- ;并显示和数。
- INCLUDE Irvine32.inc
- EXTERN PromptForIntegers@0:PROC
- EXTERN ArraySum@0:PROC, DisplaySum@0:PROC
- ;为方便起见,重新定义外部符号
- ArraySum EQU ArraySum@0
- PromptForIntegers EQU PromptForIntegers@0
- DisplaySum EQU DisplaySum@0
- ;修改 Count 来改变数组大小:
- Count = 3
- .data
- prompt1 BYTE "Enter a signed integer: ",0
- prompt2 BYTE "The sum of the integers is: ",0
- array DWORD Count DUP(?)
- sum DWORD ?
- .code
- main PROC
- call Clrscr
- ;PromptForIntegers (addr prompt1, addr array, Count)
- push Count
- push OFFSET array
- push OFFSET prompt1
- call PromptForIntegers
- ;sum = ArraySum(addr array, Count)
- push Count
- push OFFSET array
- call ArraySum
- mov sum,eax
- ;DisplaySum(addr prompt2, sum)
- push sum
- push OFFSET prompt2
- call DisplaySum
- call Crlf
- exit
- main ENDP
- END main