В этом разделе мы поработаем с программой, один модуль которой написан на паскале, а другой — на языке ассемблера.
Пример программы
Наша программа будет устроена так: основной модуль на паскале считывает со стандартного потока ввода два числа и вызывает процедуру из модуля на языке ассемблера, которая находит наибольшее из них. Основной модуль затем печатает максимум.
Модуль calc
Вспомогательный модуль на ассемблере содержит процедуру smax , в заголовке которой сразу за ключевым словом proc перечислены параметры, x и y — типа sdword (signed double word, знаковое двойное слово), и max — типа near (то есть адрес, куда будет записан результат):
; result^ := max(x, y) smax proc x: sdword, y: sdword, result: near
Примечание. Для использования функции smax в другом модуле на языке ассемблера эту функцию надо объявить так: smax proto :sdword, :sdword, :near .
По умолчанию MASM, видя спецификацию параметров, генерирует для процедуры пролог и эпилог. Мы отключим это поведение при помощи директивы option :
Рисуем в среде программирования Pascal
option prologue: none option epilogue: none
Код модуля целиком выглядит так:
Модуль main
В модуле main , который мы напишем на паскале, нам потребуется указать, что мы собираемся вызывать внешнюю процедуру smax . Для этого мы объявим ее вот так:
После этого мы сможем пользоваться процедурой smax как обычной паскалевской процедурой.
Программа целиком выглядит так:
Компиляция и компоновка
Оба модуля: main.pas и calc.asm — надо поместить в один каталог, например, C:workpascal .
Сначала оттранслируем модуль calc , чтобы получить объектный файл:
C:workpascal>ml /nologo /c /coff /Fl calc.asm
После этого можо будет скомпилировать главный модуль на паскале привычным нам способом, при этом компоновка исполняемого файла будет выполнена компилятором Free Pascal:
C:workpascal>fpc main.pas
Для удобства можно создать такой файл build.bat :
Источник: warmland.ru
Функция Concat
Функция Concat в Паскале объединяет несколько строк в одну. Синтаксис:
function Concat(const S1 : string; const S2 : string; const S3 : string; const Sn : string) : string;
Функция объединения строк Concat в Паскале объединяет строки S1, S2 и т.д. в одну строку, и возвращает полученную строку в качестве результата. Если итоговая строка получается слишком длинной, то она усекается до 255 символов (точнее, до 255 байт).
Как соединить две строки в одну
Объединение строк в Паскале можно выполнить и без использования каких-либо функций — с помощью оператора +. Например, так:
s := ‘Hello!’ + ‘ WORLD!’;
Разумеется, так можно объединить не только две, но и более строк. Кроме того, в правой части выражения могут быть не только константы, но и переменные.
Однако не во всех языках программирования такое счастье возможно. Поэтому стоит помнить, что есть специальные функции для объединения строк. Например, описываемая здесь функция Concat.
В эту функцию вы можете передать несколько строковых констант или переменных, а на выходе получите строку, в которой соединены все переданные в функцию строки (слева направо по порядку передачи в функцию Concat).
Пример программы см. ниже:
program concatfunc; var s : string; s1 : string = ‘The END!’; s2 : string = ‘ ‘; s3 : string = ‘Press ENTER. ‘; //**************************************************************** // ОСНОВНАЯ ПРОГРАММА //**************************************************************** begin s := ‘Hello!’ + ‘ WORLD!’; WriteLn(s); s1 := Concat(s1, s2, s3); WriteLn(s1); ReadLn; end.
Источник: info-master.su
Как передать информацию по сети (UDP сокеты в Lazarus)
Для передачи информации от одной программы к другой можно применить один из сетевых протоколов, таких как UDP. Он позволяет быстро обмениваться любыми данными между двумя или несколькими работающими параллельно программами, причем как на одном ПК, так и на других компьютерах в сети.
Причем не важно на каком языке программирования эти программы будут работать, данный сетевой интерфейс сможет их объединить.
Для реализации такой связи в данной статье будет показано применение технологии сетевых UDP сокетов на базе среды разработки Lazarus IDE на языке free pascal.
К сожалению, в сети на данный момент информация о данном типе соединения отрывочная, или слишком усложненная. Это не дает разобраться с базовыми моментами организации такой технологии. Поэтому здесь показана минимально необходимые действия для осуществления передачи информации по сети по протоколу UDP.
Библиотека Synapse
Организацией различного рода связей занимается библиотека Synapse Ararat. Она уже применялась для подключения к Ардуино по последовательному порту. Это описывалось в статьях о передаче информации в текстовой и бинарной форме.
Скачать библиотеку можно из официального репозитория. Для подключения необходимых функций достаточно скопировать следующие файлы в папку с проектом:
- blcksock.pas
- synacode.pas
- synafpc.pas
- synaip.pas
- synautil.pas
- synsock.pas
- sswin32.inc (для windows)
Порядок организации связи
Для осуществления связи делаем следующие процедуры:
- Подключаем модуль blcksock
- Создаем класс потока для прослушивания входящих сообщений
- Старт класса прослушивания порта (сервера)
- Процесс получения сообщения
- Процесс передачи сообщения
- Освобождение памяти потока сервера
Подключаем модуль blcksock
После того, как добавлены необходимые файлы, нужно добавить в проект модуль в раздел uses.
uses . blcksock; //модуль сетевых сокетов
Он подключить все другие необходимые модули.
Создаем класс потока для прослушивания входящих сообщений
Для того, чтобы сервер смог ждать входящих сообщений и не тормозить основную программу, нужно создать параллельный поток. Для этого нужно объявить новый класс-наследник класса TThread — базового потока. Это делается в разделе type.
type < UDPServer >// Класс для прослушивания порта в отдельном потоке TUDPServer = class(TThread) private FSocket:TUDPBlockSocket; // объект UDP сокета приема message: String; // принятое сообщение protected procedure Execute;override; // Функция ожидания сообщения параллельно procedure TakeMessage; // Функция передачи сообщения основной программе end;
В нем объявляется переменные для доступа к порту UDP сокета, принятого сообщения и функции проверки порта, отправки принятого сообщения основной программе.
Старт класса прослушивания порта (сервера)
Здесь нужно выполнить два условия: 1. создать глобальную переменную в разделе var для доступа к потоку сервера, 2. выделить для него память и запустить, например при нажатии на кнопку или при старте программы.
var // глобальный раздел переменных . Server : TUDPServer; // объект UDP сервера implementation . //Где-то в программе, например в функции нажатии на кнопку Server:=TUDPServer.Create(True);// Создание объекта сокета Server.Priority:=tpNormal; // Приоритет использования профессора Server.Start; // Запуск прослушивания порта
Процесс получения сообщения
Здесь наполняются две функции созданного класса TUDPServer.
Первая — Execute открывает сокет, его привязка к локальному IP и порту.
Причем если указать номер порта прослушивания sPort один, а отправки — другой, то можно выделить главную и подчиненные приложения. Главная — посылает сообщение подчиненным и наоборот.
Вторая — TakeMessage обращается к элементам основной программы для передачи принятого сообщения.
Процесс передачи сообщения
Для передачи сообщения другой программе (серверу) можно создать новый UDP сокет, а затем есть два пути — соединить с конкретным IP для приватной передачи или выбрать широковещание (EnableBroadcast(True)), тогда тут устанавливается маска IP.
Порт для передачи cPort выбирается таким, на котором где-то запущено его прослушивание (сервер).
Для удобства приводится готовая функция отправки сообщения обеими методами. MessageText — текст сообщения, IP — указывается адрес получателя или пустую строку », в таком случае будет использоваться маска широковещания BrodcastIP (которую нужно указать напрямую, константой или из формы).
// Отправка сообщения procedure TForm1.SendMessage(MessageText: string; IP:string); var s: string; SendSock: TUDPBlockSocket; begin S:=Format(‘%s:%s’,[User.Text,MessageText]); SendSock:=TUDPBlockSocket.Create; try SendSock.createsocket; if IP=» then // отправка всем begin SendSock.EnableBroadcast(True); SendSock.Connect(BrodcastIP,cPort); end else SendSock.Connect(IP,cPort);//отправить отдельно по IP SendSock.SendString(s); //if SendSock.LastError<>0 then // Обработка ошибки finally SendSock.Free; end; end;
Чтобы отправить сообщение нужно просто вызвать эту функцию где-то в программе.
SendMessage(‘Сообщение’,»);//Отправка сообщения всем SendMessage(‘Сообщение’,’192.168.0.3′);//Отправка сообщение конкретному IP, например 192.168.0.3
Освобождение памяти потока сервера
При остановке сервера лучше очистить занимаемую сервером память.
// Остановка сервера Server.Terminate; // Остановить поток сервера Server.WaitFor; // Ожидание окончания процессов Server.Free; // Освобождение памяти
Пример UDP клиент-сервера — чат
Для понимания полной картины работы с UDP сокетов в Lazarus, была разработана программа сетевого чата.
Этот проект можно использовать как шаблон или даже как самостоятельное приложение сетевого чата. Для этого нужно просто запустить приложение несколько раз и правильно настроить (показано в видео).