flat assembler
Message board for the users of flat assembler.
Index
> Main > IntToStrW (64-Bit) |
Author |
|
revolution 03 Feb 2024, 11:08
What do you mean by "unicode string"? Do you want a wide string (i.e. two bytes per character)?
|
|||
03 Feb 2024, 11:08 |
|
nasm 03 Feb 2024, 11:10
revolution wrote: What do you mean by "unicode string"? Do you want a wide string (i.e. two bytes per character)? Widestring is used in 90% of the cases so it would be wise to assume so. Which means you are not all that wise. Maybe you should let somebody else deal with this? I guess you can call me "Being somewhat DIRECT" This is not the place for we do coding here. _________________ Do you think anyone will sell their soul over a 10 cent yoghurt with a bad after taste that lasts, a decade? |
|||
03 Feb 2024, 11:10 |
|
macomics 03 Feb 2024, 12:45
What is the problem with encoding ANSI string to WideString. It is enough to simply add zero characters after one.
fasm1 x86 INT64->ANSI Code: UintToStr: ; edx:eax = unsigned int64, ecx = char[24] push edi push esi push ebp push ebx push ecx xor esi, esi xor ebp, ebp xor ebx, ebx mov edi, edx mov ecx, 100 test edi, edi jnz .dq cmp eax, ecx mov ecx, 0xA3D70A3E jae .dd pop edi mov ch, 10 push edi cmp al, ch jae .last or al, '0' stos byte [edi] jmp .quit @@: shrd ebp, ebx, 8 shrd ebx, edx, 8 inc esi .dq: xor edx, edx xchg eax, edi div ecx xchg eax, edi div ecx test edi, edi jnz @b mov ecx, 0xA3D70A3E mov edi, edx @@: shrd ebp, ebx, 8 shrd ebx, edi, 8 inc esi .dd: mov edi, eax mul ecx mov eax, edx shr eax, 6 imul edx, eax, 100 sub edi, edx cmp eax, 100 jae @b mov edx, edi pop edi mov ecx, 2568 push edi div ch or eax, '00' cmp al, '0' jz @f stos byte [edi] @@: mov al, ah stos byte [edi] mov eax, edx test esi, esi jz .last @@: shld edx, ebx, cl div ch shld ebx, ebp, cl or ax, '00' shl ebp, cl sub dh, dh stos word [edi] mov eax, edx dec esi jnz @b .last: div ch or ax, '00' stos word [edi] .quit: mov eax, edi mov [edi], dh pop ecx sub eax, ecx pop ebx pop ebp pop esi pop edi retn IntToStr: ; edx:eax = signed int64, ecx = char[24] cmp edx, 0 jge UintToStr push 0 push 0 sub [esp + 0], eax sbb [esp + 4], edx pop eax pop edx inc ecx call UintToStr dec ecx jc @f inc eax mov byte [ecx], '-' @@: retn fasm1 x86 DigitalANSI->WIDE Code: DigitalANSI2WIDE: ; eax = characters, ecx = wchar_t[24] pushfd push edi push esi lea esi, [ecx + eax - 1] lea edi, [ecx + eax * 2 - 2] mov ecx, eax mov ah, 0 std @@: lods byte [esi] stos word [edi] loop @b pop esi pop edi popfd retn Code: WideStr2Int: ; eax = wchar_t[24], out edx:eax, ecx = break pointer pushfd push esi push ebp push ebx push 0 cld mov ecx, 10 mov esi, eax xor ebx, ebx xor ebp, ebp cmp word [esi], '-' jnz .start lods word [esi] inc dword [esp] jmp .start @@: xchg eax, ebp mul ecx test edx, edx jnz @f xchg eax, ebx mul ebx add eax, ebp adc edx, ebx jc @f mov ebx, eax mov ebp, edx .start: lods word [esi] sub ax, '0' cmp ax, 9 jbe @b @@: pop ecx jecxz @f xor eax, ebx xor edx, edx sub eax, ebx sbb edx, ebp jmp .exit @@: mov eax, ebx mov edx, ebp .exit: lea ecx, [esi - 2] pop ebx pop ebp pop esi popfd retn |
|||
03 Feb 2024, 12:45 |
|
nasm 03 Feb 2024, 14:41
Anyone have 64-bit versions? Faster is better. You want to have this in good quality, it's a very important and frequently used routine. I'm not saying the one posted is bad, but I'm saying that if anyone have a better one, it is welcome.
_________________ Do you think anyone will sell their soul over a 10 cent yoghurt with a bad after taste that lasts, a decade? |
|||
03 Feb 2024, 14:41 |
|
nasm 03 Feb 2024, 15:47
Anyone who wants to share their proud work, don't be afraid to. Sharing is believing.
Your work will be handled professionally, and with care. |
|||
03 Feb 2024, 15:47 |
|
macomics 03 Feb 2024, 16:19
A lot of things have been optimized for proposed function:
As a result: Code: Converting the number 999`999`999 to a string 100`000`000 times Performance test (NULL_FUNC) = 133 ms wsprintfA = 8514 ms wsprintfW = 8283 ms Performance test (NULL_FUNC) = 257 ms Stack = 4610 ms Performance test (NULL_FUNC) = 241 ms BCDv3 = 3202 ms ; <<< Int2Str Performance test (NULL_FUNC) = 144 ms Delphi.internal = 23228 ms Delphi.write = 5781 ms Performance test (NULL_FUNC) = 112 ms BCB6.internel = 7722 ms BCB6.write = 6243 ms Converting the number 123 to a string 1`000`000`000 times Performance test (NULL_FUNC) = 1505 ms wsprintfA = 40110 ms wsprintfW = 35956 ms Performance test (NULL_FUNC) = 2263 ms Stack = 12650 ms Performance test (NULL_FUNC) = 2878 ms BCDv3 = 7336 ms ; <<< Int2Str Performance test (NULL_FUNC) = 1461 ms Delphi.internal = 193737 ms Delphi.write = 13918 ms Performance test (NULL_FUNC) = 1220 ms BCB6.internel = 24880 ms BCB6.write = 15985 ms Converting numbers [0 .. 4`294`967`295] to a string Performance test (NULL_FUNC) = 6313 ms wsprintfA = 386826 ms wsprintfW = 373225 ms Performance test (NULL_FUNC) = 10083 ms Stack = 220307 ms Performance test (NULL_FUNC) = 12421 ms BCDv3 = 145853 ms ; <<< Int2Str Performance test (NULL_FUNC) = 6531 ms Delphi.internal = 1017640 ms Delphi.write = 137686 ms Performance test (NULL_FUNC) = 6321 ms BCB6.internel = 352538 ms BCB6.write = 293513 ms Performance test (NULL_FUNC) - This is a test loop call with an empty function of the corresponding prototype to find out the execution delays created by the loop and the framing of the function (prologue and epilogue) wsprintfX - Windows Stack - A function that uses a shortened division cycle, but stores data on the stack BCDv3 - Current Int2Str Delphi.internal - IntToStr from Delphi 7 (in the DLL library) Delphi.write - A function written manually in Delphi 7 (in the DLL library) BCB6.internel - IntToStr from Borland C Builder v6.0 (in the DLL library) BCB6.write - A function written manually in Borland C Builder v6.0 (in the DLL library) The number from the line 'Performance test (NULL_FUNC)' above lines with test must be subtracted in order to compare results. But even without this, you can see which function works better. |
|||
03 Feb 2024, 16:19 |
|
macomics 03 Feb 2024, 17:34
In general, if you just correct e to r for all registers, then everything will work for 128-bit numbers.
I will test the speed of work later Code: Uint2Str: ; rdx:rax = unsigned int128, rcx = char[40] .magic = 0xA3D70A3D70A3D70A ; = 64 * 10000000000000000h / 100 push rdi push rsi push rbp push rbx push rcx mov rbx, rdx or rbp, -1 xor rsi, rsi xor rdi, rdi mov ecx, 100 test rbx, rbx jnz .qd cmp rax, rcx mov rcx, .magic jae .dq mov ch, 10 mov rbx, [rsp] cmp al, ch jae .last or al, '0' mov byte [rbx], al inc rbx jmp .quit @@: shrd rdi, rsi, 8 shrd rsi, rbp, 8 shrd rbp, rdx, 8 .qd: xor rdx, rdx xchg rax, rbx div rcx xchg rax, rbx div rcx test rbx, rbx jnz @b mov rbx, rdx mov rcx, .magic @@: shrd rdi, rsi, 8 shrd rsi, rbp, 8 shrd rbp, rbx, 8 .dq: mov rbx, rax mul rcx mov rax, rdx shr rax, 6 imul rdx, rax, 100 sub rbx, rdx cmp rax, 100 jae @b mov ecx, 2568 mov edx, ebx div ch mov rbx, [rsp] or eax, '00' cmp al, '0' jz @f mov [rbx], al inc rbx @@: mov al, ah mov [rbx], al inc rbx mov eax, edx test rbp, rbp js .last @@: shld rdx, rbp, cl div ch shld rbp, rsi, cl or ax, '00' shld rsi, rdi, cl sub dh, dh mov [rbx], ax shl rdi, cl mov eax, edx add rbx, 2 test rbp, rbp jns @b .last: div ch or ax, '00' mov [rbx], ax add rbx, 2 .quit: pop rcx mov rax, rbx mov [rbx], dil sub rax, rcx pop rbx pop rbp pop rsi pop rdi clc retn IntToStr: ; rdx:rax = signed int128, rcx = char[48] cmp rdx, 0 jge UintToStr push 0 push 0 sub [rsp + 0], rax sbb [rsp + 4], rdx pop rax pop rdx inc rcx call UintToStr dec rcx jc @f inc rax mov byte [rcx], '-' @@: retn |
|||
03 Feb 2024, 17:34 |
|
nasm 03 Feb 2024, 20:53
I haven't tested it yet, I will look at it soon. Great work, looks complicated.
|
|||
03 Feb 2024, 20:53 |
|
SeproMan 04 Feb 2024, 19:47
Quote: Do anyone have a procedure to convert a 64-bit signed integer to a unicode string. A solution for Linux: Code: ; IN (rdi,rsi) OUT (rax) MOD (rcx,rdx,rdi) IntToStrW: push rsi ; (1) sub rsp, 24 ; At most 19 digits mov rax, rsp xchg rax, rdi ; -> RAX is 64-bit integer, RDI is temp buffer (stack) mov ecx, 10 ; CONST RCX = 10 test rax, rax jns .more mov word [rsi], '-' add rsi, 2 neg rax .more: xor edx, edx div rcx ; RDX:RAX / RCX add edx, '0' mov [rdi], dl inc rdi test rax, rax jnz .more .copy: dec rdi movzx eax, byte [rdi] mov [rsi], ax add rsi, 2 cmp rdi, rsp ja .copy add rsp, 24 mov rax, rsi pop rsi ; (1) sub rax, rsi shr eax, 1 ; -> RAX is number of unicode characters ret A solution for Windows: Code: ; IN (rcx,rdx) OUT (rax) MOD (rcx,r8,r9) IntToStrW: push rdx ; (1) mov r9, rdx sub rsp, 24 ; At most 19 digits mov rax, rsp xchg rax, rcx ; -> RAX is 64-bit integer, RCX is temp buffer (stack) mov r8d, 10 ; CONST R8 = 10 test rax, rax jns .more mov word [rdx], '-' add r9, 2 neg rax .more: xor edx, edx div r8 ; RDX:RAX / R8 add edx, '0' mov [rcx], dl inc rcx test rax, rax jnz .more .copy: dec rcx movzx eax, byte [rcx] mov [r9], ax add r9, 2 cmp rcx, rsp ja .copy add rsp, 24 mov rax, r9 pop rdx ; (1) sub rax, rdx shr eax, 1 ; -> RAX is number of unicode characters ret _________________ Real Address Mode. |
|||
04 Feb 2024, 19:47 |
|
nasm 05 Feb 2024, 09:39
Keep in mind folks that StrToInt is also a welcome solution. It goes in any direction. Your work is appreciated. Will test it later. Thanks guys and ladies and buddies.
|
|||
05 Feb 2024, 09:39 |
|
macomics 08 Feb 2024, 21:56
I found some free time and tested version of 64-bit function, which I wrote in browser using a calculator here
The constant that I calculated on the calculator can't be used to replace div by mul for 64-bit numbers. It gives errors from the very beginning of the range of natural numbers. I have not yet been able to find a constant to replace 64-bit division with multiplication. But I can suggest the following function, which has been checked for correctness. By sunday, I will test several variants of the functions for performance and post the results. Code: ; WIDE ; ANSI IntToStr: ; rdx:rax = signed int128, rcx = char[48]; mod: r8, r9 cmp rdx, 0 jge UintToStr mov r8, rax mov r9, rdx xor rax, rax cqo add rcx, 2 ; inc rcx sub rax, r8 sbb rdx, r9 call UintToStr lea rcx, [rcx - 2] ; dec rcx jc @f inc rax mov word [rcx], '-' ; mov byte [rcx], '-' @@: retn UintToStr: ; rdx:rax = signed int128, rcx = char[48]; mod: r8, r9 .magic = 0xA3D70A3E ; 1 + 64 * 0x10000000000000000 div 100 push rdi push rsi push rbp push rbx push rcx mov rbx, rdx or rbp, -1 xor rsi, rsi xor rdi, rdi mov ecx, 2568 mov r9, 0xFFFFFFFF00000000 mov r8, 100 test rbx, rbx jnz .qd test rax, r9 jnz .dq cmp rax, r8 mov r8d, .magic jae .dd mov rbx, [rsp] cmp al, ch jae .last or eax, '0' mov [rbx], ax ; mov [rbx], al add rbx, 2 ; inc rbx jmp .quit @@: shrd rdi, rsi, cl shrd rsi, rbp, cl shrd rbp, rdx, cl .qd: xor rdx, rdx xchg rax, rbx div r8 xchg rax, rbx div r8 test rbx, rbx jnz @b @@: shrd rdi, rsi, cl shrd rsi, rbp, cl shrd rbp, rdx, cl .dq: xor rdx, rdx div r8 test rax, r9 jnz @b mov ebx, edx mov r8d, .magic @@: shrd rdi, rsi, cl shrd rsi, rbp, cl shrd rbp, rbx, cl .dd: mov ebx, eax mul r8d mov eax, edx shr eax, 6 imul edx, eax, 100 sub ebx, edx cmp eax, 100 jae @b mov ecx, 2568 mov edx, ebx div ch mov rbx, [rsp] or eax, '00' cmp al, '0' jz @f shl eax, cl ; <remove> xchg al, ah ; <remove> mov [rbx], ax ; mov [rbx], al add rbx, 2 ; inc rbx shr eax, cl ; <remove> @@: shr eax, cl mov [rbx], ax ; mov [rbx], al add rbx, 2 ; inc rbx mov eax, edx test rbp, rbp js .last @@: div ch shld rdx, rbp, cl or ax, '00' shld rbp, rsi, cl shl eax, cl ; <remove> shld rsi, rdi, cl xchg al, ah ; <remove> mov [rbx], eax ; mov [rbx], ax shl rdi, cl movzx eax, dl add rbx, 4 ; add rbx, 2 test rbp, rbp jns @b .last: div ch or ax, '00' shl eax, cl ; <remove> xchg al, ah ; <remove> mov [rbx], eax ; mov [rbx], ax add rbx, 4 ; add rbx, 2 .quit: pop rcx mov rax, rbx mov [rbx], r9w ; mov [rbx], r9b sub rax, rcx shr al, 1 ; <remove> pop rbx pop rbp pop rsi pop rdi retn Now the following modifications are present in this function:
|
|||
08 Feb 2024, 21:56 |
|
macomics 11 Feb 2024, 16:22
As promised, I tested various options for the functions. You will find their implementations in the attached archive. All functions have been checked for the correctness of converting numbers into strings (numbers do not have leading zeros and end with a character with the code 0, and even more so they coincide with the original number after the reverse conversion).
Function 1 - uses a non-shortened translation cycle (two divisions per digit) and a non-shortened conversion cycle (one char at a time). Function 2 - does not use a shortened translation cycle (two divisions per digit), but reduces the conversion cycle (by dividing by the square of the base = 100). Function 3 - uses a shortened translation cycle (two divisions per digit until the highest part of the 128-bit number is zeroed, then one at a time), and a non-shortened conversion cycle (one char at a time). Function 4 - uses a shortened translation cycle (two divisions per digit until the highest part of the 128-bit number is zeroed, then one at a time), and reduces the conversion cycle (by dividing by the square of the base = 100). Function 5 - uses a twice-shortened translation cycle (two divisions per digit before zeroing the highest part of a 128-bit number, then one division before zeroing the highest part of a 64-bit number and a cycle of divisions expressed through multiplications for 32-bit numbers), and a non-shortened conversion cycle (one character at a time). Function 6 - uses a twice-shortened translation cycle (two divisions per digit before zeroing the highest part of a 128-bit number, then one division before zeroing the highest part of a 64-bit number and a cycle of divisions expressed through multiplications for 32-bit numbers), and reduces the conversion cycle (by dividing by the square of the base = 100). Version 'S' - uses a stack to buffer digits. The 'R' version uses registers. Version 'A' - generates ASCII characters. The 'W' version is WideChar. The 'Cur' version is used by me (although I will probably return the previous one now). The 'Old' version is the previous version of the function I am using. Code: --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test name | IntToStr_v1SA | IntToStr_v2SA | IntToStr_v3SA | IntToStr_v4SA | IntToStr_v5SA | IntToStr_v6SA | IntToStrCur | IntToStrOld | wsprintfA | wsprintfW | IntToStr_v1RA | IntToStr_v2RA | IntToStr_v3RA | IntToStr_v4RA | IntToStr_v5RA | IntToStr_v6RA | | | | | IntToStr_v1SW | IntToStr_v2SW | IntToStr_v3SW | IntToStr_v4SW | IntToStr_v5SW | IntToStr_v6SW | | | | | IntToStr_v1RW | IntToStr_v2RW | IntToStr_v3RW | IntToStr_v4RW | IntToStr_v5RW | IntToStr_v6RW | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test32 0 | 40,465102 | 27,062468 | 19,584408 | 14,722758 | 3,890590 | 3,698597 | 5,935235 | 5,177087 | 34,669194 | 31,648878 | 45,971380 | 29,127479 | 20,691218 | 15,837081 | 5,683810 | 5,156656 | | | | | 40,950618 | 27,188282 | 19,629393 | 16,243488 | 3,707793 | 4,257237 | | | | | 46,047060 | 30,062751 | 21,234906 | 16,594077 | 5,726811 | 6,072606 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test32 1 | 92,051504 | 44,609781 | 41,478786 | 24,117753 | 7,781698 | 7,756330 | 11,571971 | 8,643268 | 57,881268 | 57,037049 | 101,176805 | 53,171002 | 51,132716 | 27,984795 | 13,913113 | 12,108637 | | | | | 92,168039 | 51,071010 | 42,046187 | 26,680333 | 7,750881 | 9,380711 | | | | | 101,250950 | 57,820211 | 51,499064 | 32,794736 | 13,923139 | 16,091782 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test32 2 | 1,141072 | 0,650029 | 0,496988 | 0,308176 | 0,100212 | 0,090782 | 0,156103 | 0,120643 | 0,673903 | 0,664181 | 1,184458 | 0,699826 | 0,608439 | 0,376070 | 0,166694 | 0,146282 | | | | | 1,142848 | 0,661379 | 0,499384 | 0,347342 | 0,101524 | 0,112249 | | | | | 1,187946 | 0,762256 | 0,615211 | 0,433289 | 0,167109 | 0,184783 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test64 3 | 3,314981 | 1,725764 | 1,633232 | 0,894895 | 1,018157 | 0,597882 | 0,805450 | 0,689710 | - | - | 3,522207 | 2,106134 | 1,856625 | 1,273519 | 1,200720 | 0,951388 | | | | | 3,314903 | 1,811896 | 1,633203 | 0,978236 | 1,020433 | 0,680179 | | | | | 3,526217 | 2,300655 | 1,865511 | 1,466905 | 1,222308 | 1,146217 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test64 4 | 108,754703 | 60,924724 | 49,042170 | 29,860293 | 8,897663 | 8,670448 | 15,334207 | 11,838544 | - | - | 119,697428 | 71,046716 | 61,107990 | 37,709629 | 16,616310 | 14,541726 | | | | | 108,909579 | 64,384195 | 49,388848 | 34,461131 | 8,863242 | 10,400419 | | | | | 119,876236 | 76,741607 | 61,486518 | 43,373020 | 17,035374 | 18,260533 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test64 5 | 15,898995 | 8,268931 | 7,518533 | 4,201759 | 2,156827 | 1,800477 | 2,772112 | 2,207858 | - | - | 17,360790 | 9,476832 | 8,992276 | 5,362431 | 3,227618 | 2,991756 | | | | | 15,893796 | 8,706692 | 7,525887 | 4,539428 | 2,153175 | 2,336504 | | | | | 17,370066 | 10,622754 | 9,030594 | 6,481560 | 3,314039 | 3,949815 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test128 6 | 8,862853 | 4,953373 | 7,221445 | 4,063538 | 6,588030 | 3,822474 | 4,181027 | 3,985687 | - | - | 9,371115 | 5,913213 | 7,648396 | 5,055771 | 6,977727 | 4,727004 | | | | | 8,925735 | 5,122470 | 7,315418 | 4,234970 | 6,612387 | 3,922024 | | | | | 9,345278 | 6,154636 | 7,580831 | 5,312088 | 6,929218 | 4,950434 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test128 7 | 3,886227 | 2,071753 | 2,276122 | 1,286343 | 1,671305 | 0,983787 | 1,214280 | 1,093103 | - | - | 4,308330 | 2,640669 | 2,504311 | 1,818897 | 1,861156 | 1,487809 | | | | | 3,897550 | 2,167384 | 2,285433 | 1,396126 | 1,678297 | 1,073904 | | | | | 4,113681 | 2,768264 | 2,492403 | 1,970451 | 1,841311 | 1,647236 | | | | --------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+---------------- Test32 0 > 123 @ 1`000`000`000 Test32 1 > 123456 @ 1`000`000`000 Test32 2 > [0xFFFF`FFFF`FFFF`FFFF`FFFF`FFFF`FA0A`1F00 .. 0xFFFF`FFFF`FFFF`FFFF`FFFF`FFFF`FFFF`FFFF] Test64 3 > [0xFFFF`FFFF`FA0A`1F00 .. 0xFFFF`FFFF`FFFF`FFFF] Test64 4 > [0 .. 999`999`999] Test64 5 > 9`876`543`210 @ 100`000`000 Test128 6 > 0x7FFF`FFFF`FFFF`FFFF`FFFF`FFFF`FFFF`FFFF @ 10`000`000 Test128 7 > 0x05F5`E100`0000`0000`0000 .. 0x0000`0001`0000`0000`0000 / 0x0001`0000`0000`0000 By the way, I didn't expect my old version of the working function to be better than the current one.
|
|||||||||||
11 Feb 2024, 16:22 |
|
SeproMan 16 Feb 2024, 19:19
Quote: Keep in mind folks that StrToInt is also a welcome solution. Next codes assume that the unicode text is a valid representation of a signed 64-bit number. So there is at least one decimal digit, optionally prepended with a minus and always followed by a terminating zero. A solution for Linux: Code: ; IN (rdi) OUT (rax) MOD (rdx) StrToIntW: push rdi ; (1) String address xor rax, rax cmp word [rdi], '-' jne .more add rdi, 2 ; Skip minus .more: movzx edx, word [rdi] ; RDX now holds a digit add rdi, 2 lea rax, [rax + rax * 4] ; RAX = RAX * 10 + NewDigit lea rax, [rdx + rax * 2 - 48] cmp word [rdi], 0 jne .more pop rdi ; (1) Restore string address cmp word [rdi], '-' jne .done neg rax .done: ret A solution for Windows: Code: ; IN (rcx) OUT (rax) MOD (rdx) StrToIntW: push rcx ; (1) String address xor rax, rax cmp word [rcx], '-' jne .more add rcx, 2 ; Skip minus .more: movzx edx, word [rcx] ; RDX now holds a digit add rcx, 2 lea rax, [rax + rax * 4] ; RAX = RAX * 10 + NewDigit lea rax, [rdx + rax * 2 - 48] cmp word [rcx], 0 jne .more pop rcx ; (1) Restore string address cmp word [rcx], '-' jne .done neg rax .done: ret _________________ Real Address Mode. |
|||
16 Feb 2024, 19:19 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.