Question: inline assembler, better leave it? lazarus / 21-General ---------------------------------------------------------------------- d7_2_laz · 2021-03-29 15:05 Lazarus 2.0.12, Windows 10 x64: From an older component / VirtualShellTools, Delphi 7  i have as leftover inline assembler coding that does not compile. As i even do not know for sure if it's recommended to use inline assembler with Win x64: is it recommeded not to pursue such an approach? The statements are: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function StrRScanW(Str: PWideChar; Chr: WideChar): PWideChar;// returns a pointer to the last occurance of Chr in Strasm       PUSH    EDI       MOV     EDI, Str       MOV     ECX, 0FFFFFFFFH       XOR     AX, AX     REPNE   SCASW       NOT     ECX       STD       SUB     EDI, 2     MOV     AX, Chr       REPNE   SCASW       MOV     EAX, 0       JNE   @@1       MOV     EAX, EDI       ADD     EAX, 2@@1:       CLD       POP     EDIend; ---------------------------------------------------------------------- 440bx · 2021-03-29 15:24 In general assembly code should be avoided for multiple reasons, among them, it is very often bitness dependent and it is often a pain to maintain. For the function you showed and, if you don't mind a Windows only solution, NTDLL exports the function wcsrchr which does exactly what that code does.  The non unicode version is also present with the name strrchr. Note: NTDLL exports just about all the string functions available in the C rtl and quite a few additional ones that the C rtl does not have.  IOW, there are string functions galore in NTDLL. HTH. ---------------------------------------------------------------------- ASerge · 2021-03-29 15:50 Quote from: d7_2_laz on March 29, 2021, 05:05:03 pm...i have as leftover inline assembler coding that does not compile This compiled by FPC 3.2.0 32x: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODE OBJFPC} {$ASMMODE INTEL}function StrRScanW(Str: PWideChar; Chr: WideChar): PWideChar; assembler; register; nostackframe;// returns a pointer to the last occurance of Chr in Strasm       PUSH    EDI       MOV     EDI, Str       MOV     ECX, 0FFFFFFFFH       XOR     AX, AX     REPNE   SCASW       NOT     ECX       STD       SUB     EDI, 2     MOV     AX, Chr       REPNE   SCASW       MOV     AX, 0       JNE   @@1       MOV     EAX, EDI       ADD     EAX, 2@@1:       CLD       POP     EDIend; beginend. For x64, you need to change the operands and registers. By the way, I found a bug in FPC 3.2.0 x64. This not compiled: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODE OBJFPC} {$ASMMODE INTEL}function StrRScanW(Str: PWideChar; Chr: WideChar): PWideChar; assembler; register; nostackframe;// returns a pointer to the last occurance of Chr in Strasm       PUSH    RDI       MOV     RDI, Str       MOV     ECX, 0FFFFFFFFH       XOR     AX, AX     REPNE   SCASW       NOT     ECX       STD       SUB     EDI, 2     MOV     AX, Chr // problem line       REPNE   SCASW       MOV     EAX, 0       JNE     @@1       MOV     EAX, EDI       ADD     EAX, 2@@1:       CLD       POP     RDIend; beginend. But compiles by FPC 3.3.1. Slightly tweaked code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODE OBJFPC} {$ASMMODE INTEL}function StrRScanW(Str: PWideChar; Chr: WideChar): PWideChar; assembler; register; nostackframe;// returns a pointer to the last occurance of Chr in Strasm       PUSH    RDI       MOV     RDI, Str       MOV     ECX, 0FFFFFFFFH       XOR     AX, AX     REPNE   SCASW       NOT     ECX       STD       SUB     EDI, 2     MOV     EAX, DWORD PTR Chr // Strange, but complied       REPNE   SCASW       MOV     EAX, 0       JNE     @@1       MOV     EAX, EDI     ADD     EAX, 2@@1:       CLD       POP     RDIend; beginend. Compiled by FPC 3.2.0, but not FPC 3.3.1. ---------------------------------------------------------------------- d7_2_laz · 2021-03-29 16:42 Thank you both for confirmation resp. feedback! In the special case mentioned i think i'd rather replace the whole caller funtion of StrRScanW by an appropriate eqquivalent. It's used for for to create an "UniqueFileName" and there should probably exist  a better way. I'm just, looking at (project.pp:) TProject.NewUniqueFilename; maybe there are others. After your responses i feel it would be better not to dig in bitness dependencies or register correctness for that special purpose. ---------------------------------------------------------------------- PascalDragon · 2021-03-30 07:27 Quote from: d7_2_laz on March 29, 2021, 05:05:03 pmLazarus 2.0.12, Windows 10 x64: From an older component / VirtualShellTools, Delphi 7  i have as leftover inline assembler coding that does not compile. As i even do not know for sure if it's recommended to use inline assembler with Win x64: is it recommeded not to pursue such an approach? Aside from whether it's a good idea or not to use inline assembly: you can't expect to use assembly written for i386 as is on another platform (which x86_64 is). Best approach if you do use inline assembly is to always have a non-assembly fallback so that you can use that for other platforms where you haven't done the inline assembly implementation (yet). For example even with the suggestions by the others your code would still fail if compiled for Windows on ARM64 (okay, maybe aside from 440bx's suggestion of using wcsrchr from ntdll ) ---------------------------------------------------------------------- d7_2_laz · 2021-03-30 17:48 Yes PascalDragon, fully agree. - In my special case i tried to avoid such and rewrote the calling procedure (pascal). Many thanks for all of your replies and hints! ---------------------------------------------------------------------- Nitorami · 2021-03-30 19:03 Can't you simply use sysutils.strrscan ? Synopsis: Find last occurrence of a character in a null-terminated string. Declaration: function strrscan(p: PChar; c: Char) : PChar function strrscan(p: PWideChar; c: WideChar) : PWideChar ---------------------------------------------------------------------- d7_2_laz · 2021-03-31 08:40 Oh - that should be surely another possibility to do .. Thanks for the hint!