А что делать? StringCbPrintf заменить? Вот блин, ещё изучать :\ А может кусками как-то wsprintf, а потом lstrcat? а длину буфера как подчистить или NULL? Код (Text): invoke wsprintf,a,'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112' invoke wsprintf,b,'345' invoke lstrcat,a,b invoke MessageBoxTimeout,HWND_DESKTOP,a,'',MB_TOPMOST,LANG_NEUTRAL,5000 Впринципе работает, но 345345345 целый килобайт ещё в хвост :lol: --- Сообщение объединено, 4 май 2025 --- Интересно, можно ли так обойти ограничение Код (Text): include '%fasm%/win64ax.inc' section '.code' executable start: sub rsp,8 invoke wsprintf,a,'123' invoke lstrcat,a,i invoke wsprintf,b,'678' invoke lstrcat,a,b invoke MessageBoxTimeout,HWND_DESKTOP,a,'',MB_TOPMOST,LANG_NEUTRAL,5000 exit: invoke ExitProcess,NULL section '.data' readable i db '45',NULL section '.data' readable writeable a rb MAX_PATH b rb MAX_PATH То есть нарастить огромный файл по частям. Получается! Ура! --- Сообщение объединено, 5 май 2025 --- wsprintf + wsprintf + wsprintf
Research, программирование на ассемблере ― удел людей с извращенной фантазией. Так что смиритесь, это карма ...
Как же без извратов Код (Text): VEH proc X:ptr EXCEPTION_POINTERS mov eax,X mov ecx,EXCEPTION_POINTERS.ExceptionRecord[eax] mov edx,EXCEPTION_POINTERS.ContextRecord[eax] .if EXCEPTION_RECORD.ExceptionCode[Ecx] == STATUS_SINGLE_STEP assume edx:ptr CONTEXT mov eax,[edx].rEip .if Eax != offset Break movzx ecx,B[eax] sub ecx,0B8h .if !Carry? && (Cl < 8) && (D[Eax][1] == 400h) not ecx mov [edx].rEax[ecx*4][4],10000h add [edx].rEip,5 .endif or [edx].rEFlags,100h .endif mov eax,EXCEPTION_CONTINUE_EXECUTION .else mov eax,EXCEPTION_CONTINUE_SEARCH .endif ret VEH endp Entry proc invoke RtlAddVectoredExceptionHandler, 1, addr VEH push 100h popfd invoke wsprintfA, addr V, addr F Break:: ret Entry endp
в си sprintf возвращает длину напечатанной в строковый буфер строки в винде - нет? можно strcat сэкономить вообще тут код выглядит если даже и работоспособным, то максимально небезопасным с точки зрения расходования стека - потому что конструкция вида %c%c%c%c%c%c%c%c%c%c требует столько же 32 бит слов поместить в стек и быстродействие будет так себе из-за необходимости парсить отдельно каждый так печатаемый байт тут разумный подход выглядел бы в рукописном аналоге sprintf, где каждый элемент формата от % до след пробела, % или " копируется из источника данных (п0ля СУБД как пример) отдельно и тут же сливается в WriteFile если длинные символьные поля источника мы помещаем как есть посредством гирлянды %c то и это дешевле проделать записью буфера оптом на диск через вызов WriteFile тем самым мы не ограничены длиной каждой подстроки и общей длиной получаемого xml
Не всегда. Иногда хочется из своего кода пару функций на асм перевести, чтобы все было быстрее, но из меня кодер на ассемблере, как из говна пуля.
Мне главное дистрибутив, fasm.exe - один файл, IDE как блокнот! И такая мощь, правда мозги если приложить, но это везде так, мозг нужен)) А если си, я там половина дистрибутива не знаю, всякий треш на диске будет лежать. Это для работы в корпорации) Или если в Линукс сидишь и там весь треш уже в дистрибутив входит, так же как теперь .NET в Windows
Semiono, Три способа есть задачу решить. Трассировать, транслировать и пересобрать всю процедуру. Какой вам нравится ?
Решить задачу нравится) Не знаю, я думаю что я решил. Маленький конфиг xml пишется по частям. Сам код у меня ещё запускает прогу, выравнивает окно итд итп. Просто я был в шоке, когда буфер закончился, вначале я думал это глюк, все %s пересчитывал)) Но теперь знаю как обойти ограничение.
Код (ASM): .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib .data ; Test strings testStr db 1024 dup("1"), 0 ; Long string of 1's testStr2 db "222", 0 ; Short string to append testStr3 db "333", 0 ; Another short string ; Buffers buffer1 db 2048 dup(0) ; Buffer for wsprintf attempt buffer2 db 2048 dup(0) ; Buffer for concatenation solution tempBuf db 1024 dup(0) ; Temporary buffer ; Format strings fmt1 db "Testing wsprintf with long string:", 13, 10 db "First attempt with direct wsprintf:", 13, 10 db "%s", 0 fmt2 db "Now testing concatenation method:", 13, 10 db "%s%s%s", 0 ; Messages caption1 db "Direct wsprintf Test", 0 caption2 db "Concatenation Test", 0 msgSuccess db "Test completed successfully!", 0 .code start: ; Test 1: Direct wsprintf (will show limitation) invoke wsprintf, addr buffer1, addr fmt1, addr testStr invoke MessageBox, NULL, addr buffer1, addr caption1, MB_OK ; Clear buffer invoke RtlZeroMemory, addr buffer1, 2048 ; Test 2: Solution using concatenation invoke lstrcpy, addr buffer2, addr testStr invoke lstrcat, addr buffer2, addr testStr2 invoke lstrcat, addr buffer2, addr testStr3 ; Show result of concatenation invoke MessageBox, NULL, addr buffer2, addr caption2, MB_OK ; Show completion message invoke MessageBox, NULL, addr msgSuccess, NULL, MB_OK invoke ExitProcess, 0 end start Вот так может? --- Сообщение объединено, 5 май 2025 --- Вот advanced
с точки зрения include ассемблер ничем не хуже си, и там и там удобно повторяющиеся части текста, будь то одинаковые процедуры (чтение файла и тп) или описания структур данных WinApi вынести в отдельные и редко изменяемые файлы, а редактируемый код изолировать в небольших по числу строк модулях так уже за счет навигации по тексту можно выиграть время что касается треша на диске, в установленном VC скорее всего найдутся в том числе исходники sprintf() из MS VC runtime и скорее всего можно себе скомпилировать приватную версию sprintf с буфером желаемой длины, или как минимум посмотреть листинг на ассемблере кода, в который превратился этот исходник на си. или вырезать из статической библиотеки один объектный файл и его одного дизассемблировать, почему нет.