#1 mORMot 1 » Length of unicode string by pointer in new PosExStringPas... » 2019-12-04 11:19:31

Amir
Replies: 1

Hi dear Arnaud,

As PChar is compiled with {$POINTERMATH ON}, direct pointer arithmatic operations should be applied with the multiplication of the pointer's base type-size with the value specified by operation.

Thus in for eg:

function PosExStringPas(pSub, p: PChar; Offset: PtrUInt): PtrInt;

We calculate the length of the "p" and "pSub" in Delphi version as

PInteger(p - 4)^; //and so for "pSub"

This actually is computed as "PByet(p) - 8", Where Char is two-byte sized (in Unicode Versions of Delphi).

Seems it should be edited for both "p" and "pSub" as for eg:

PInteger(PByte(p) - 4)^;

For always correct access to string's length field.

Please let me know if I am wrong...

Thanks.

#2 Re: mORMot 1 » Delphi 10.2 Tokyo Compatibility » 2017-03-22 19:50:58

Hi all
Could any one witness any compiled-code performance enhancements in comparison with previous versions (10-10.1.x) !!??
At least in Win32 compiler, as for Win64 the compilation process always fails as noticed..

And dear Arnaud,
It would be very thankful if you let us know about the quality of generated code with the very new LLVM-based Linux compiler, as I remembered, you mentioned somewhere the final generated code produced using Delphi mobile compilers are not so optimized; may be due to unqualified settings applied to the LLVM-backend...
I'd like to know if this new server-support-release also suffers from the same performance issue !!??

Thanks in advance.

#3 Re: mORMot 1 » About the ticket [ca41b5d79a], as you (ab) requested. » 2015-04-12 19:08:33

Yes,
I was just testing all different aspects of the mORMot framework for better understanding of myself from its operations, I ran the tests in both logging enabled and disabled states, and as always you're right, almost no performance difference !!! Great work by all means.
Thanks.

#4 mORMot 1 » About the ticket [ca41b5d79a], as you (ab) requested. » 2015-04-10 08:12:30

Amir
Replies: 2

Hi dear Arnaud,

In the following code snippet:

destructor TSQLHTTPRestServer.Destroy;
begin
  fLog.Enter(Self).Log...  // the rest of the code line.
  {the rest of the destructor routine}
end;

when this destructor is called with {$define WITHLOG}, everything goes right and it works like a charm, but if we do compile with "WITHLOG" directive undefined, an AV occurs when the destructor is called.

Seems the "fLog" field in above code snippet is not instanciated, as it may not being used by any other means of the framework. I think that code-line above should be surrounded with a {ifdef WITHLOG}{endif} pair - like many other parts of your code - to prevet this issue.

To reproduce this issue you can compile the Client/Server official example with "WITHLOG" undefined.

I think it is a simple and small regression which remained hidden as the most of times we all compile our code with {define WITHLOG}.
And please excuse me for that unclear ticket, I should have explained more. Actually I created the ticket in a situation that I was very in a hurry.

Thanks.

#5 Re: mORMot 1 » Track change-type (Add/Update/Delete) of records when replication... » 2015-04-03 23:42:35

ab wrote:

Don't be shy, and spread the word on mORMot around you:

You can be sure that I'll do my best !!!, I honestly believe mORMot deserves much more. But unfortunately Delphi (Pascal in general) and its related market is relatively small and heavily disposed to use visual-friendly and RAD components and tools which need the least possible coding efforts. Obviously with the current community concerns, it takes this great framework more time to be well-known and accepted !

I'd like to have a serous try to make it available for .NET ASAP (Using C++/CLI to minimize the overhead of managed/native code interaction), I also like to let services be introduced in JavaScript/TypeScript (something like Node.js) using the integrated SpiderMonkey engine, as well as in .NET in Visual Studio, but I really need to spend much more time with mORMot to get more and more familiar with its low level operations and of course your SOS !!!.

ab wrote:

I've seen a job offer in France last week especially asking for mORMot skills.
Small, but nice move!
big_smile

Very nice and very happy to hear that...

#6 Re: mORMot 1 » Probable connection fail in presence of proxies !!! » 2015-04-03 19:47:28

ab wrote:

How do you want to make the connection check?
By sending  a ping on the other side?

Hi,

"Ping" uses an ICMP echo, so it is expected to work with any active connection regardless of being run within a network-tunnel (if we assume there would be NO blocking firewall-roles or route-maps). As the problem is basically the web-socket itself, we should send the traffic directly through the currently upgraded web-socket and get the result(s) back; in order to validate its functionality.

You have introduced a method to check the server availability as "TSQLRestClientURI.ServerTimeStampSynchronize()" which performs fast and simple pulling. After the web-socket's handshake - which is HTTP-based -, the rest of connection semantics uses web-socket's standards; so if the "upgrade" is satisfied, any other traffic should be transferred in web-socket's way. Therefore "ServerTimeStampSynchronize()" should fulfill the need.

What is your idea ??

As you may know https://www.websocket.org/echo.html implements an echo-server using HTML5 web-sockets. Here you can use a VPN (using different tunneling protocols) to reveal the problem, as the problem is also noticed on the page.

To be honest I think implementing HTML5 Web-sockets was a very nice try, but unfortunately it is not so accepted by many active network-devices' configurations, simply because it is very young and not widely used, today.
This great technology works nice on a local-host, but may not work as expected in a real world use-case.

For example; consider xDSL users which are connected to their ISPs using a tunnel (very common), they simply may have problems with web-socket connections and also offices/organizations which use proxies and different network tunneling services for different purposes (Security, Segmentation and Net. Traffic management) and ... They all may have unsuccessful experiment with their web-sockets-powered apps.

As I mentioned in my earlier post, secure web-sockets (wss://) using TLS may fail in very rare situations and seem to be operational in real world projects. so if we want to have a safe and working web-socket service with today's common network settings, we'd better use secure web-sockets i.e: over TLS.

But as you yourself noticed, IMHO the best and always working solution to implement a bidirectional, asynchronous, and REST-friendly publish-subscribe collaboration mechanism, for today's mORMot; is hiring a message queue system, as the great, light, cross-platform, open-source and of course very fast "0MQ" - which you also liked.

...and as always, thanks for you great work.

Best.

#7 mORMot 1 » Probable connection fail in presence of proxies !!! » 2015-04-03 13:20:03

Amir
Replies: 2

Hi Dear Arnaud.

I took a look at "THttpClientWebSockets.WebSocketsUpgrade()" method's implementation, I think we need an additional connection check even if the WS-upgrade reported successfully. As you may know WS connections may fail in presence of many widely used tunneling-services, especially with regular websocket connections. WSS (TLS Enabled) websockets may pass this step with much much greater chance (very rare to fail). As the use of tunneling [for security reasons, logical network segmentation, traffic control (bandwidth management) and ...] seems very common, I think such a solution should be considered.

Thanks.

#8 Re: mORMot 1 » Track change-type (Add/Update/Delete) of records when replication... » 2015-04-02 11:59:34

ab wrote:
Amir wrote:

Thank you very much for this and also for the great "TSQLRestServer.RecordVersionSynchronizeCallback()" feature.

This feature is still in implementation stage: not tested, and with some potential changes.

Thanks for your notice... But I was very excited about introducing another great feature that satisfies my current project's need in a very simple way. But I know as a convention, if a road-map listed feature or important-update is completed and well tested, most of time a dedicated blog post is born and "self-tests" group of projects involve new test-cases...

To be honest, I've been familiar with Synopse Tools and mORMot framework since 2010-2011, and I followed its progress periodically by checking the timeline and reading your great blog posts (introducing new features and/or challenging other tools/technologies AND sharing experiences and ideas) and also some forum discussions; And as many other things I decided to use mORMot multiple times and unfortunately this never achieved, but these days I'm feeling deeply integrated with your mORMots' life-cycle !!!, as I'm carefully studding mORMot's documentation (Very detail and intensive !!! Thanks.) as well as some most-visited forum topics in addition to reviewing/reading blog posts. (WOWWW !!! GREAT WORK... REALLY GREAT CROSS-PLATFORM OPEN SOURCE PROJECT IN PASCAL WORLD !!!).

THANKS FOR SUCH A GREAT WORK...

#9 Re: mORMot 1 » Track change-type (Add/Update/Delete) of records when replication... » 2015-04-02 06:39:26

Thank you very much for this and also for the great "TSQLRestServer.RecordVersionSynchronizeCallback()" feature.

#10 mORMot 1 » Track change-type (Add/Update/Delete) of records when replication... » 2015-04-01 12:13:59

Amir
Replies: 6

Hi dear Arnaud,

Thanks for implementing the great master/slave replication feature.

I've recently downloded the latest repository and I'd like to use it as main backend in my current project, with this I need to manage a list of products to report and highlight new and/or updated items to the end users (Clients), as appropriate. As far as I studied the correspondig ducumenation, I could not find out how to reflect the change-type applied to a record; for example, I need to know which items are new to my client(s) and which comes as updates.
It would be very helpful for me and also for same scenarios, if you provide such feature or if currently available let me know how to get it used.

As a simple proposal, it would be nice if you let an optional callback parameter in "TSQLRestClient.RecordVersionSynchronize" which receives the "new" (recently retreived from master) and "old" (available with the current processing slave) "TSQLRecordVersion"s, and for new records the old-version value could be set to TSQLRecord(-1) for example; and for deleted records, implementing a new method which lets the clients fetch deleted item-IDs for any TSQLRecord (which directly queries the dedicated deletion-track table; i.e: "TSQLRecordTableDelete", if necessary) seems enough.

Thanks for your great work.

#11 Re: mORMot 1 » Save huge file-stream (considered about 2GB) in a Table as BLOB. » 2014-05-29 11:57:53

Thanks for your quick answer; Of course I also prefer to use dedicated files; but here security matters...
I've to hide the files from direct view and access !!!

I'd be thankful, if you suggest better solutions.

#12 mORMot 1 » Save huge file-stream (considered about 2GB) in a Table as BLOB. » 2014-05-29 08:39:11

Amir
Replies: 6

Hi, I need to store large-sized blobs in a local SQlite database, I'd like to know if anyone has advices or tricks for tuning and better performance gain.

Thanks in advance.

#14 mORMot 1 » Problem with Token-Prefix MATCH Queries in a FTS4 SQLite Table » 2014-05-26 16:25:34

Amir
Replies: 2

Hi,
When I post this query

"SELECT ROWID FROM UserData WHERE UserData MATCH 'UserID:2298691215 OR EMail:edc@edc.org';"

using ExecuteList(), the resulting TSQLTableJSON does not contain all matching records; but when I execute it (exactly the same statements) using the SQLite-Database-Editor ("SQLite Expert" in my case) everything is OK and always all records are retrieved as expected; This seems like an issue !!?.

I'm using the latest 1.18 version of mORMot.

Thanks.

#15 Re: mORMot 1 » Multithreaded data retreival... » 2014-04-13 09:40:38

Thanks alot. well working.
But is there any difference performance-wise between the use of dedicated client per thread and this new threadsafe implementation in general ?
I think there should be no (significant) difference with use of SQLite kernel but for other engines like MS SQL Server or Oracle, using a seperate client per thread may provide better scaling; Is it right ?

Thanks.

#16 Re: mORMot 1 » Multithreaded data retreival... » 2014-04-10 06:24:58

Hi ...
I tested the "04 - HTTP Client-Server" as modified like what you see in previous post in windows XP and 7 as well (and always the applications had been running with admin privileges), and they all behaved the same and the problem still persists.

Would you please help me find where I'm going wrong ?

#17 Re: mORMot 1 » Multithreaded data retreival... » 2014-04-09 15:27:14

Yes, I had run the server with admin privileges several times, not only the server but also the client app sad
I'm using win 8.1, I doubt if something within this new windows version causes that, I'll do test on win 7 and XP and post the feedback ASAP.
But one more thing that has messed up my mind is that the same problem occurs when using windows message-mode !! I think this mode should be well thread-safe and scalable...
I may be doing something wrong, would be so thankful if you help me solve this.

Thanks.

#18 Re: mORMot 1 » Multithreaded data retreival... » 2014-04-09 11:58:37

To show my exact problem I have changed sample "04 - HTTP Client-Server" a little - ofcourse only the "Project04Client" part is modified and the server-application will stay unchanged - to help with reraising the exception that I'm suffering from.


here is the modified version of unit1.dfm

object Form1: TForm1
  Left = 604
  Top = 370
  BorderStyle = bsSingle
  ClientHeight = 416
  ClientWidth = 490
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -13
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 16
  object Label1: TLabel
    Left = 40
    Top = 16
    Width = 67
    Height = 16
    Caption = 'Your name:'
  end
  object Label2: TLabel
    Left = 40
    Top = 72
    Width = 86
    Height = 16
    Caption = 'Your message:'
  end
  object Label3: TLabel
    Left = 232
    Top = 192
    Width = 37
    Height = 16
    Caption = 'Label3'
  end
  object Label4: TLabel
    Left = 48
    Top = 267
    Width = 393
    Height = 48
    AutoSize = False
    Caption = 
      'PLEASE run this application in debugging-mode within the IDE, To' +
      ' reveal and catch the OS ERROR #12019 in SynCrtSock unit which I' +
      #39'm suffering from.'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clRed
    Font.Height = -13
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
    ShowAccelChar = False
    WordWrap = True
  end
  object Label5: TLabel
    Left = 48
    Top = 326
    Width = 393
    Height = 54
    AutoSize = False
    Caption = 
      'I tried to show the exact system error number and its correspond' +
      'ing message, but its not simply possible;  as it may be overwrit' +
      'ten with other consequent errors or even reset.'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -13
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
    ShowAccelChar = False
    WordWrap = True
  end
  object QuestionMemo: TMemo
    Left = 32
    Top = 88
    Width = 409
    Height = 121
    ScrollBars = ssVertical
    TabOrder = 0
  end
  object NameEdit: TEdit
    Left = 32
    Top = 32
    Width = 217
    Height = 24
    TabOrder = 1
  end
  object AddButton: TButton
    Left = 48
    Top = 232
    Width = 145
    Height = 25
    Caption = 'Add the message'
    TabOrder = 2
    OnClick = AddButtonClick
  end
  object QuitButton: TButton
    Left = 312
    Top = 232
    Width = 129
    Height = 25
    Caption = 'Quit'
    TabOrder = 3
    OnClick = QuitButtonClick
  end
  object FindButton: TButton
    Left = 256
    Top = 32
    Width = 185
    Height = 25
    Caption = 'Find a previous message'
    TabOrder = 4
    OnClick = FindButtonClick
  end
  object Button1: TButton
    Left = 48
    Top = 384
    Width = 393
    Height = 25
    Caption = 'Please add a message and check this'
    TabOrder = 5
    OnClick = Button1Click
  end
end

and this is the modified version of unit1.pas

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,
  SynCommons, mORMot,
  SampleData, System.Contnrs;

type

  TTestThread = class(TThread)
  private
    P: TSQLSampleRecord;
    FOccured: Boolean;
  protected
    procedure Execute; override;
  public
    destructor Destroy; override;
  end;

  TForm1 = class(TForm)
    QuestionMemo: TMemo;
    NameEdit: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    AddButton: TButton;
    QuitButton: TButton;
    FindButton: TButton;
    Button1: TButton;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    procedure AddButtonClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure QuitButtonClick(Sender: TObject);
    procedure FindButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    FList: TObjectList;
  public
    Database: TSQLRest;
    Model: TSQLModel;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TTestThread }

destructor TTestThread.Destroy;
begin
  inherited Destroy;
  P.Free;
end;

procedure TTestThread.Execute;
var LError: Cardinal;
begin
  if P = nil then
    P := TSQLSampleRecord.Create;
  while not (Terminated or FOccured) do begin
    Form1.Database.Retrieve(1, P, False);
    LError := GetLastError;
    if LError <> ERROR_SUCCESS then begin
      FOccured := True;
      Synchronize(
        procedure
        begin
          Form1.QuestionMemo.Lines.Add(Format('Error Code: %d'#13#10'Error Message: %s'#13#10'=========',
              [LError, SysErrorMessage(LError)]));
        end
      );
    end;
  end;
end;

procedure TForm1.AddButtonClick(Sender: TObject);
var Rec: TSQLSampleRecord;
begin
  Rec := TSQLSampleRecord.Create;
  try
    // we use explicit StringToUTF8() for conversion below
    // a real application should use TLanguageFile.StringToUTF8() in mORMoti18n
    Rec.Name := StringToUTF8(NameEdit.Text);
    Rec.Question := StringToUTF8(QuestionMemo.Text);
    if Database.Add(Rec,true)=0 then
      ShowMessage('Error adding the data') else begin
      NameEdit.Text := '';
      QuestionMemo.Text := '';
      NameEdit.SetFocus;
    end;
  finally
    Rec.Free;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FList.Free;
  Database.Free;
  Model.Free;
end;

procedure TForm1.QuitButtonClick(Sender: TObject);
begin
  Close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var I: NativeInt;
begin
  for I := 0 to 9 do
    FList.Add(TTestThread.Create);
end;

procedure TForm1.FindButtonClick(Sender: TObject);
var Rec: TSQLSampleRecord;
begin
  Rec := TSQLSampleRecord.Create(Database,'Name=?',[StringToUTF8(NameEdit.Text)]);
  try
    if Rec.ID=0 then
      QuestionMemo.Text := 'Not found' else
      QuestionMemo.Text := UTF8ToString(Rec.Question);
  finally
    Rec.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Model := CreateSampleModel; // from SampleData unit
  FList := TObjectList.Create(True);
end;

end.

Please run the client application with debugging enabled within the IDE to let the debugger reveal the OS error  #12019 as mORMot's SynCrtSock.pas seems fault-tolerant enough to hide that.

Please let me know if something is wrong here;

Thanks in advance.

#19 Re: mORMot 1 » Multithreaded data retreival... » 2014-04-09 11:32:56

"21 - HTTP Client-Server performance" Sample compiles with Delphi XE5 update 2; but when running, after clicking the "Start" button, an access violation halts the program execution.

The debugger points to "SynSelfTests.pas" at line #10207

{$ifdef LVCL}
if fDatabase.AquireWriteMode = amMainThread then ....
//..
//..
//..
{$endif

as LVCL is not defined in my test-case and well, the fDatabase has not been initialized; because the fDatabase is to be Created in the section

if fClientOnlyServerIP = '' then begin
  // ...
  fDatabase := TSQLRestServerDB.Create(.......);
  // the rest of operations...
end; 

and the "ClientOnlyServerIP" property is initialized in the "OnClick event of Start button" to be localhost ip-address, so the above-mentioned condition never matches and so the fDatabase is not instanciated with a TSQLRestServerDB.

it seems the first if-block should be embraced by the second one or some extra checks should be considered or ....

Thanks.

#20 mORMot 1 » Multithreaded data retreival... » 2014-04-08 12:43:21

Amir
Replies: 10

Hi dear Arnaud and THANKS FOR SUCH A GREAT FRAMEWORK...

I decide to use mORMot in my recent project and I've started to do some excercises to get fluent with mORMots' language !!
Now I've encountered a problem with a very simple test-app; this app uses TSQLRestClient.Retreive method with the definite signature of TSQLRestClient_Instance.Retreive(aID, TSQLRecord_instance, FALSE); to retreive data within background threads simultanously.
When I adapt the code to run within the main thread, everything sounds well; but when I switch to spread the retreival-tasks within threads, sometimes (NOT ALWAYS), it fails. I'd like to know if there are any notes or advices that I should consider or even this approach is a working-solution or I have to implement my retreival-task as a service and consume it at client-side using consumer-threads instead ?

(I'm using the latest version of mORMot framework (1.8.x) + its SQLite kernel as data-store, and I've tested my sample app in HTTP Client-Server and also Windows-Messages architectures and the problem still persists.).



Thanks.

#21 Low level and performance » Delphi x64 inline assembler... » 2012-03-31 22:30:05

Amir
Replies: 3

The place to exchange ideas and experiences on Delphi x64 assembly programming.

#22 Re: Delphi » Delphi Application Protection » 2010-08-26 10:21:57

Dear Arnaud,

As you know, Delphi visual forms are encoded as DFM files and included into the executables as resources (RT_RCDATA). This implementation causes that DFMs could be simply exposed to the public, and this resource leak might be harmful in some situations.

my main question, concerns about how we can prevent this... and I prefer to do it in a delphi way, not using third parties.

I searched the web and I found many utilities designed to provide secure executables and libraries, but all of them are going to protect and compress whole of executable (or libraries) that is earned with heavy overhead. then I asked this question to find a solution with the least overhead and speed penalty.

and I made a guss it could be possible if I use a compression library (something using LZO algorithms for online decompression with no memory overhead) like "SynLZO.pas" and compress only forms and data modules with password protection, and also decomress it while initializing the forms, this causes to have a smaller executable and also provides a good security.

And I agree with you about the previous topic. but I am a novice programmer and computer studet who encountered lots of problems and questions while challenging the programming languages and utilities, and I try to find the best answer to them. so I look up the answer in some related books in hand or search the web and also post my questions to good forums. and I am not producing a software so I need no protection mechanism, I just wanted to learn and practice.

Thanks.

#23 Re: Delphi » Delphi Application Protection » 2010-08-26 09:16:16

Dear Yogiyang..

Thanks..

Yoda Protector is a good and fast resource packer and protector which could be operative for most exe, dll, ocx files. it also can pack and protect delphi executables and libraries.

Please consider this article

-- Note the newer version (1.03.3), included some bug fix and improvements which had covered some issues noted in the article.

I also recommend evaluating SoftwarePassport Armadillo

#24 Delphi » Delphi Application Protection » 2010-08-23 21:14:24

Amir
Replies: 6

Hi All,

Delphi forms are accessible after compiling, through a resource viewer program (e.g. Resource Hacker, Resource Builder, Restorator, etc.). this may reveal the program logic. My question is how to protect delphi application from this risk ...

some components (e.g. Bellinium Effects Citadel) provide this facility or some applications like "WTM EXE Stealth Protector", "Logic Protect EXE Creator", "Private exe Protector", "Exe Protect" and many more, help us have much secure applications, but with a heavy overhead, ofcourse Citadel works more efficiently ...

Is there any solution with the least penalty ?

Thanks.

#25 Re: Language » Assembly Procedures and Functions » 2010-08-22 08:17:15

Hi Dear Arnaud.

And Thanks for every thing...

One more question, does delphi iteself align a for, while or repeat/until loop in an appropriate manner ???

#26 Re: Language » Assembly Procedures and Functions » 2010-08-20 20:39:53

Thanks...

I remember all your remarks. There are lots of things I should learn... I know nothing about pipelining & ..., beside documents you introduced, I've started to study "The Intel Microprocessors ... 7th Ed - Barry B. Brey". I decide to learn this completely... I love lowlevel sad

All thanks.

function NumToPersian(const str: string): string;
asm
      test  eax, eax
      xchg  eax, edx
      jz    System.@UStrClr
@@Continue:
      push  edx
      mov   edx, [edx - 4]
      push  edx
      push  eax
      push  edx
      call  System.@UStrClr
      pop   eax
      call  System.@NewUnicodeString
      pop   edx
      mov   [edx], eax
      mov   edx, eax
      pop   ecx
      pop   eax
      shr   ecx, 1
      push  ebx
      jz    @@One
      nop
@@Loop:
      dec   ecx
      mov   ebx, dword ptr [eax]
      lea   ebx, ebx + $06C006C0
      lea   eax, eax + 4
      mov   dword ptr [edx], ebx
      lea   edx, edx + 4
      jnz   @@Loop
@@One:
      mov   ebx, dword ptr [eax]
      test  bx, bx
      jz    @@Quit
      add   ebx, $6C0
      mov   dword ptr [edx], ebx
@@Quit:
      pop   ebx
end;

#27 Re: Language » Assembly Procedures and Functions » 2010-08-20 17:09:34

By the wayyyyyy....

I tried to make just one call to "UStrClr" but because it affects all the world !!! and I had to push EDX, ECX registers, I found it much better to include two "UStrClr"s !!!

Please let me know your idea, which guides me through the rest of the work....

thanks.

#28 Re: Language » Assembly Procedures and Functions » 2010-08-20 16:58:50

Hi Dear Arnaud

Here's new code, using UStrClr + NewUnicodeString, which has @@Loop at 4-byte aligned address, I tried to make an aligned loop without adding NOPs...

And about "size"... I was about aligning both address of the loop and size of the loop, this achieved by adding one extra NOP instraction before loop start-point.

It was because when studying "Intel Optimization... PDF" which you introduced, I misunderstood a subject, that after progressing in study I found it.

Sorry. sad

function NumToPersian(const str: string): string;
asm
      test  eax, eax
      xchg  eax, edx
      jnz   @@Continue
      call System.@UStrClr
      ret
@@Continue:
      push  edx
      mov   edx, [edx - 4]
      push  edx
      push  eax
      push  edx
      call  System.@UStrClr
      pop   eax
      call  System.@NewUnicodeString
      pop   edx
      mov   [edx], eax
      mov   edx, [edx]
      pop   ecx
      pop   eax
      test  ecx, 1
      jz   @@Prepare
      inc   ecx
@@Prepare:
      shr   ecx, 1
      push  ebx
@@Loop:
      dec   ecx
      mov   ebx, dword ptr [eax]
      lea   ebx, ebx + $06C006C0
      lea   eax, eax + 4
      mov   dword ptr [edx], ebx
      lea   edx, edx + 4
      jnz   @@Loop
      pop   ebx
end;

best.

#29 Re: Fast JPEG decoder » Fast JPEG decoder using SSE/SSE2 version 1.2 » 2010-08-20 08:59:05

Hi Dear Arnaud.

I have a JPEG image, which is not drawn by Fast JPEG decoder, but with TJPEGImage !!!
would u let me know the reason.

Here's the Pic: test.jpg

best.

#30 Re: Language » Assembly Procedures and Functions » 2010-08-20 08:22:53

Thanks Dear Arnaud.

I put a breakpoint at the start point of the @@Loop and using the delphi dissembler stopping at that point, I could simply calculate the size of Loop which was 11 bytes, and needed only one NOP instruction, to be DWORD aligned.

     

      .
      .
      . 
      nop
@@Loop:
      dec   ecx
      mov   ebx, dword ptr [eax]
      lea   ebx, ebx - $06C006C0
      lea   eax, eax + 4
      mov   dword ptr [edx], ebx
      lea   edx, edx + 4
      jnz   @@Loop
      .
      .
      .
      

I'll also replace the UStrSetLength with combination of UStrClr and NewUnicodeString as you advised to optimize the function.

All Thanks for ur help.
Cheers.

#31 Re: Language » Assembly Procedures and Functions » 2010-08-19 20:32:47

I'm back ... I read something about data alignment also also I decided to study delphi string managment mechanism, so I read string management routines in "system.pas" unit, and now I am aware of what happens to a string in its lifecycle... this should have been accomplished soOoOoOoner sad sad  SORRY ...
Then I found that, the problem you mentioned about "Clearing empty strings" still persists in my code. Where I'd used "NewUnicodeString" function, the string previously assigned (temp string), never cleared, if there was one. I found another function in "system.pas" which fits my needs, called "UStrSetLength". so I changed the code to provide a DWORD aligned function which manages strings using the function (UStrSetLength) correctly.

Now how can I align the loop that is the main part of the function ? --- You noticed by adding NOP at start point of the loop, but how I can have the size of my loop to define number of NOPs to apply. --- You highlited something in a comment of your code about ALT-F12 shortcut, I tried multiple times in different situations, but nothing occured, would you please help me again.

Thank You.

function NumStrToFa(const str: string): string;
asm
      xchg   eax, edx
      test   edx, edx
      jz      @@Null
      push  edx
      mov   edx, dword ptr [edx - 4]
      push  edx
      call    System.@UStrSetLength
      mov   edx, eax
      pop    ecx
      pop    eax
      mov    edx, dword ptr [edx]
      push   ebx
      shr     ecx, 1
      jz       @@one
@@Loop:
      dec    ecx
      mov   ebx, dword ptr [eax]
      lea     ebx, ebx + $06C006C0
      lea     eax, eax + 4
      mov   dword ptr [edx], ebx
      lea     edx, edx + 4
      jnz     @@Loop
@@one:
      mov   ebx, dword ptr [eax]
      test   bx, bx
      jz      @@Quit
      add    ebx, $6C0
      mov   dword ptr [edx], ebx
@@Quit:
      pop   ebx
      ret
@@Null:
      jmp   System.@UStrClr
end;

Please let me know your idea.
Cheers ...

#32 Re: Language » Assembly Procedures and Functions » 2010-08-19 17:26:59

Hi ... sad

Where can I read about data alignment !!! I know nothing about what u say sad I really like to learn why it is so important.

Know only I can make a guss of what you said about alignment, that I'll change the code and post it again.

Please let me know a complete reference about it.

as you noticed the the dummy code removed from first start of the function:

function NumStrToFa(const str: string): string;
asm
      test  eax, eax
      jz    @@Null
      push  eax
      mov   eax, dword ptr [eax - 4]
      push  eax
      .
      .
      .

The function you mentioned is "UStrClr" which shoulf be applied at the end of the function.
that should manage the emty string explicitly.

   .
   .
   .

@@Null:
      mov   eax, edx               //  preparing the result parameter for "UStrClr" function
      jmp   System.@UStrClr
end;                                  // end of the function declaration

Realllyyyy Thankssssss again.

#33 Re: Language » Assembly Procedures and Functions » 2010-08-19 14:24:04

Hi Dear Arnaud,

Thanx for ur beautiful code... I am learning from your codes vary much. smile

THANK YOU.

I had checked to prevent extra "pushing and popping" of registers, when I wrote the code; but unfortunately the "NewUnicodeString" function affects and manipulates all EAX, ECX, EDX registers' data !!!

so I had to save them to retrieve essential data needed to run the rest of code. and the couple of PUSH-POP which has surrounded the "NewUnicodeString" seems necessary, but ther is another "PUSH EDX-POP EDX" which can be ANIHILATED... as you've illustrated in your code .

I always prefer native pointers, even in pure pascal. like C/C++. but I wanted to test delphi-string manipulation using assembly, and I found it does not make me a favour !!!

I think I'd be back to pointers again, any where possible ... smile . But there is no other choice in VCL, we should challenge delphi string. sad

As you noticed I could have written such code by converting two wideChars at the same time. now I have completed this function using your code template, and I moved and replaced

and  ecx,  1 ===>  test  ecx, 1

then there is no need to have another couple of [PUSH ECX - POP ECX], and also by merging two sections ("@@nomore", "@@one") in one, we have a smaller function.

function NumStrToFa(const str: string): string;
asm
      test  eax, eax
      jz    @@Null2
      push  eax
      mov   eax, [eax - 4]
      test  eax, eax
      jz    @@Null1
      push  eax
      push  edx
      call  System.@NewUnicodeString
      pop   edx
      mov   [edx], eax
      pop   ecx
      pop   eax
      mov   edx, [edx]
      push  ebx
      test  ecx, 1
      jz    @@Loop
      shr   ecx, 1
@@one:
      mov  bx, [eax]
      add   bx, $6C0
      mov  [edx], bx
      test  ecx, ecx
      jz    @@Quit
      lea   eax, eax + 2
      lea   edx, edx + 2
@@Loop:
      dec   ecx
      mov   ebx, [eax]
      lea   ebx, ebx + $06C006C0
      lea   eax, eax + 4
      mov   [edx], ebx
      lea   edx, edx + 4
      jnz   @@Loop
@@Quit:
      pop   ebx
      ret
@@Null1:
      add   esp, 4
@@Null2:
end;

Please tell me about these changes... Thanks.

#34 Language » Assembly Procedures and Functions » 2010-08-19 04:57:43

Amir
Replies: 16

Hi all, smile

here I have written an assembly function, which converts a general numerical string to Persian - Arabic equvalent.

for example:  '1234567890'  ==>  '۱۲۳۴۵۶۷۸۹۰'

NOTE ---- all characters of the string parameter assumed to be numeric, and no further checking seems necessary.

Your ideas are welcome to help a newcomer amateur programmer optimize this little piece of code. hmm

thanx.

function NumStrToFa(const str: string): string;
asm
      test  eax, eax               // check if the string is null
      jz    @@Null2
      push  eax                    // save the input string pointer to stack
      mov   eax, [eax - 4]      // length of the input string
      test  eax, eax              // checking for emty string
      jz    @@Null1
      push  eax                   // saving the length of input string to stack
      push  edx                   // saving the @Result
      call  System.@NewUnicodeString   //creating a new string which forms the result
      pop   edx                                  // retrieving the @Result         
      mov   [edx], eax                        // assign the new string to @Result
      pop   ecx                                  // retrieving the Length of string
      pop   eax                                  // retrieving the input string pointer
      push  edx                                 // saving the Result string
      mov   edx, [edx]                        // forming the edx register to be used in the loop.
      push  ebx
@@Loop:
      mov   bx,  word ptr [eax + ecx * 2 - 2]
      add   bx,  6C0h                                      //$C0 is the  Persian-Arabic Zero character order ('۰') - '0'
      mov   word ptr [edx + ecx * 2 - 2], bx
      Loop  @@Loop
      pop   ebx
      pop   edx                                             // having the Result back
      ret
@@Null1:
      add   esp, 4
@@Null2:
end;

Board footer

Powered by FluxBB