程序使用原代码
1、掌握利用LINK将多模块连接起来的方法
设计代码如下:
;//主程序,主程序,主程序,主程序,主程序,主程序,主程序,主程序,主程序,主程序,主程序,主程序
.686
.387
.model flat, stdcall
option casemap : none
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
;includelib mylib.lib;引用自己设计的库
extrn result:REAL4 ;EXTERN在汇编中用来引用一个在其他模块中定义过的符号名,使得这个符号名所表示的数据或函数能在该模块中被使用。
extrn deal:near
.data
Table EQU THIS BYTE;//宏定义 定义了9个初值分别为1,2,3,4...9的字节单元,Table为这些字节单元的首地址
COUNT = 1
REPT 9
DB COUNT
COUNT = COUNT + 1
ENDM
T DW ?
ZERO REAL4 0.0
.code
start :
MOV CX, 9;//设置循环次数
FLD ZERO;//给栈顶置零
LEA ESI, Table;//把DS:Table的偏移地址给ESI,用于寄存器间接寻址
sum:
CMP CX, 0
JE calculation;//如果CX为零则跳转到calculation段
MOV AX, 0
MOV AL, [ESI]
MOV T, AX
FILD T;//FILD指令将16位 32位或者64位有符号整数源操作数转换为双精度浮点数,并加载到ST(0)。源操作数符号保留。FILD支持的内存操作数类型和MOV一致
FADD
ADD ESI, 1
LOOP sum;//本来这句是CX为零就不执行跳转的语句,但是不知道为什么没有实现????
calculation:
FSTP result
call deal;进入子程序
invoke ExitProcess,NULL
end start
;//子程序,子程序,子程序,子程序,子程序,子程序,子程序,子程序,子程序,子程序,子程序
.686
.387
.model flat, stdcall
option casemap : none
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
includelib mylib.lib
public deal;该伪指令告诉汇编程序放在PUBLIC之后的标识符(本模块的定义的)可为其他模块使用,这些标识符可以是变量,标号或者过程名.
public result
.data
result REAL4 ?
F REAL4 ?
L1 REAL4 0.000001; 32位
C1 REAL4 0.000001
TWO REAL4 2.0
ONE REAL4 1.0
_size DW 80
.code
deal proc c ;proc是定义子程序的伪指令,位置在子程序的开始处,它和endp分别表示子程序定义的开始和结束两者必须成对出现。
;我也没搞懂为啥要写proc c ,有知道的可以帮忙解释
FLD L1; //将L1入栈
FMUL C1; //ST < -(C1) * (ST)
FSQRT; //ST < -sqrt(ST)
FMUL TWO; //ST < -(TWO) * (ST)
FLDPI; //ST < -PI
FMUL;//ST<-ST(1)*ST
FLD ONE;//ST <- 1
FDIVR;//ST <- ST/ST(1)
FLD result
FMUL
FSTP F;//F<-ST
ret;ret指令的内部操作是:栈顶字单元出栈,其值赋给IP寄存器。即实现了一个程序的转移,将栈顶字单元保存的偏移地址作为下一条指令的偏移地址。
;这里就理解成返回到主程序的子程序入口指令的下一条指令
deal endp
end
调试程序方法,因为没有交互式输出,我们采用调试的方式查看程序结果,如果要查看子程序的变量值,就要在子程序中加入断点,具体操作如下:
F10单步调试,通过监视窗口可见到ST0的值为:7161972.4572175322(没错就是这个)
或者可按照书上的link两个obj文件,生成一个.exe文件是可行的,下面我们来探索比较复杂的库文件方法。
2、掌握利用库文件将多模块连接起来的方法。
在自己的项目文件中->Debug文件夹中找到子程序的.obj文件复制到masm32文件夹的bin目录下,因为不想一会儿敲文件地址。。。
打开命令行程序,进入到masm32的bin目录下,执行如下操作,即可生成mylib.lib文件:
然后一定要把生成的mylib.lib文件放在masm32的lib中,千万要看到,我就不插图了,费劲死了。
为了实验的正确性,我们删除项目中的deal.asm(子程序)代码,和Debug中的deal.obj(子程序obj文件),将文件中的includelib mylib.lib的注释取消。Ctrl+F7重新编译一下:
先F10单步调试,然后在调试->窗口->反汇编(最下面,一定要先开调试,再找),然后在反汇编界面找到deal子程序(可能需要稍微往下翻一翻),然会在反汇编的第一行代码加断点,F5跳到断点,F10单步执行就可以查看了。。。(好麻烦,我就摸索出来这一种,如果谁有更好的方法,请大神留言)。
比较繁琐,如果读者有更好的方式能调试汇编库函数,请与我联系。