Трансляция.
tasm32 /ml calc.asm brcc32 calc.rcЗатем в проект к программе calcc.cpp (на Рис. 3.8.7) добавим файлы calc.obj и calc.res.
Рис. 3.7.9. Пример работы программы-калькулятора (Рис. 3.7.7-3.7.8).
V
Теперь поговорим о встроенном ассемблере. Это весьма мощное средство. Надо только иметь в виду, что встроенные ассемблеры часто несколько отстают от обычных ассемблеров в части поддержки новых команд микропроцессоров. Это вполне объяснимо, так как разработка новой версии пакета, скажем C++ Builder, требует гораздо больше времени, чем пакета TASM. В примерах на Рис. 3.7.10 и Рис. 3.7.11 мы используем команды арифметического сопроцессора.
program Project2; {$APPTYPE CONSOLE} uses SysUtils; var d:double; function soproc(f:double): double; var res:double; begin asm FLD f FSIN FSTP res end; soproc:=res; end; begin d:=-pi; while (d<=pi) do begin writeln(d:10:2,'-',soproc(d):10:2); d:=d+0.1; end; end.
Рис. 3.7.10. Пример использования директивы ASM и команд сопроцессора в программе на языке Паскаль (Delphi 5.0).#include <windows.h> #include <stdio.h> double soproc(double f); void main() { double w=-3.14; while(w<=3.14) { printf("%f- %f\n", w, soproc(w)); w=w+0.1; } ExitProcess(0); } double soproc(double f) { double d; asm { FLD f FSIN FSTP d } return d; }VI
В заключение я хочу привести пример того, как динамическая библиотека, созданная на Delphi, может быть использована в программе на языке ассемблера. Некоторое время назад я нашел алгоритм, реализованный на Delphi, который помещает ярлык программы на рабочий стол и одновременно делает пункт в меню Программы (Пуск). Я сам на Delphi не пишу, но времени на переписывание алгоритма на Си у меня не было, и я из программы сделал динамическую библиотеку, которой теперь с успехом пользуюсь при создании различных инсталляционных пакетов.
Данный пример предполагает посылки в процедуру четырех параметров: две ссылки на программы, название ярлыка на рабочем столе и название пункта меню. Вы можете при желании расширить возможности данной процедуры. Если Вы посмотрите на ассемблерный модуль, то увидите, что никаких особых отличий вызова данной динамической библиотеки нет.
library lnk; uses SysUtils, Classes, Windows, ShlObj, ActiveX, ComObj, Registry, syncobjs; procedure setup(prog:PChar; uns: PChar; jar:PChar; menu:PChar); stdcall; var MyObject : IUnknown; MySLink : IShellLink; MyPFile : IPersistFile; FileName : String; Directory : String; WFileName : WideString; MyReg : TRegIniFile; ps1,ps2,sn,path,s :string; nb:dword; handle : integer; l:DWORD; f: text; begin MyObject := CreateComObject(CLSID_ShellLink); MySLink := MyObject as IShellLink; MyPFile := MyObject as IPersistFile; FileName := prog; path := ExtractFilePath(FileName); with MySLink do begin SetArguments(''); SetPath(PChar(FileName)); SetWorkingDirectory(PChar(ExtractFilePath(FileName))); end; // вначале ярлык на экране MyReg : = TRegIniFile.Create('Software\MicroSoft\Windows\CurrentVersion\Explorer'); Directory := MyReg.ReadString('Shell Folders','Desktop',''); WFileName := Directory+'\'; WFileName := WFileName+jar; WFileName := WFileName+'.lnk'; MyPFile.Save(PWChar(WFileName),False); ps1:=string(WFileName); // создание ярлыка в главном меню Directory :=MyReg.ReadString('Shell Folders','Programs','')+'\'; Directory:=Directory+menu; WFileName := Directory+'\'; WFileName := WFileName+jar; WFileName := WFileName+'.lnk'; CreateDir(Directory); ps2:=Directory+'\'; MyPFile.Save(PWChar(WFileName),False); //************************************ MyObject:= CreateComObject(CLSID_ShellLink); MySLink:= MyObject as IShellLink; MyPFile := MyObject as IPersistFile; FileName := uns; path := ExtractFilePath(FileName); with MySLink do begin SetArguments(''); SetPath(PChar(FileName)); SetWorkingDirectory(PChar(ExtractFilePath(FileName))); end; WFileName := Directory+'\'; WFileName := WFileName+'UNFILES.lnk'; MyPFile.Save(PWChar(WFileName),False); MyReg.Free; // создать файл, куда будет помещена // нужная для дальнейшей инсталляции информация sn:=path+'perebros.lnk'; AssignFile(f,sn); rewrite(f); writeln(f,ps1); writeln(f,ps2); close(f); end; //********************* Procedure DLLMain(r:DWORD); begin end; exports setup; begin DLLProc:=@DLLMain; DLLMain(dll_Process_Attach); end.