将字符附加到 masm 程序集中的 'db' 变量

Appending character to a 'db' variable in masm assembly

刚开始学汇编,卡住了。 我在 WPARAM 变量中有一个字符(也可以是 DWORD ),我必须将它附加到 db 字符串。我不知道该怎么做。 这是我的代码:

.386
.model flat, stdcall
option casemap: none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

include C:\Program Files\masm32\include\windows.inc
include C:\Program Files\masm32\include\kernel32.inc
include C:\Program Files\masm32\include\user32.inc
include C:\Program Files\masm32\include\gdi32.inc


includelib "C:\Program Files\masm32\lib\kernel32.lib"
includelib "C:\Program Files\masm32\lib\user32.lib"
includelib "C:\Program Files\masm32\lib\gdi32.lib"

.data
cn db "Parth",0
an db "Priydarshi Singh",0
char WPARAM 21h
text db "A",0
ps DWORD ?
hin HINSTANCE ?
cmd LPSTR ?

.code
start:
    invoke GetModuleHandle, 0
    mov hin, eax
    invoke GetCommandLine
    mov cmd, eax
    invoke WinMain, hin, 0, cmd, SW_SHOWDEFAULT
    invoke ExitProcess, 0

    WinMain proc inst:HINSTANCE, pinst:HINSTANCE, cml:LPSTR, show:DWORD

        LOCAL wc:WNDCLASSEX
        LOCAL msg:MSG
        LOCAL hwnd:HWND

        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_VREDRAW or CS_HREDRAW
        mov wc.lpfnWndProc, offset WndProc
        mov wc.cbClsExtra, 0
        mov wc.cbWndExtra, 0
        push hin
        pop wc.hInstance 
        mov   wc.hbrBackground,COLOR_WINDOW+1 
        mov   wc.lpszMenuName,NULL 
        mov   wc.lpszClassName,OFFSET cn 
        invoke LoadIcon,NULL,IDI_APPLICATION 
        mov   wc.hIcon,eax 
        mov   wc.hIconSm,eax 
        invoke LoadCursor,NULL,IDC_ARROW 
        mov   wc.hCursor,eax 
        invoke RegisterClassEx, addr wc

        invoke CreateWindowEx, NULL, addr cn, addr an, WS_OVERLAPPEDWINDOW, 0, 0, 1366, 750, NULL, NULL, inst, NULL

        mov hwnd, eax
        invoke ShowWindow, hwnd, show
        invoke UpdateWindow, hwnd

        .WHILE TRUE
            invoke GetMessage, addr msg, NULL, 0, 0
            .BREAK .IF(!eax)
            invoke TranslateMessage, addr msg
            invoke DispatchMessage, addr msg
        .ENDW

        mov eax, msg.wParam
        ret

    WinMain endp

    WndProc proc hwnd:HWND, umsg:UINT, wp:WPARAM, lp:LPARAM

        LOCAL hdc:HDC
        LOCAL rect:RECT

        .IF umsg==WM_DESTROY
            invoke PostQuitMessage, 0

        .ELSEIF umsg==WM_CHAR
            push wp
            pop eax
            mov char, eax
            ; I need some code here to append 'char' to 'text' 
            invoke InvalidateRect, hwnd, NULL, TRUE

        .ELSEIF umsg==WM_PAINT
            invoke BeginPaint, hwnd, addr ps
            mov hdc, eax
            invoke TextOut, hdc, 0, 100, addr text, sizeof text
            invoke EndPaint, hwnd, addr ps

        .ELSE
            invoke DefWindowProc, hwnd, umsg, wp, lp
            ret

        .ENDIF

        xor eax, eax
        ret

    WndProc endp

end start

如果有 space 可用的附加字符,您只能附加到字符串。

您已将 text 声明为 text db "A",0,它在 text'A'0)处保留 2 个字节,因此没有空间附加字符。如果您知道字符串的最大长度,您仍然可以静态分配它;例如 text db 1024 dup(0) 会给你 1024 个字节的 space,其中所有字节的初始值都是 0。如果你有另一个变量来跟踪字符串中的当前字符数,你可以使用它来追加到字符串:

mov edi,text_length
mov [text + edi],al
inc dword ptr text_length

如果您的字符串可以收缩也可以增长,那么当您从字符串中提取 "remove" 个字符时,您必须确保在正确的位置插入一个 NUL 终止符。

如果事先不知道字符串的最大长度,或者最大值很大,可以使用Windows提供的内存分配函数之一动态分配内存,例如HeapAlloc。如果字符串即将增长到超过当前分配的大小,您可以使用 HeapReAlloc 增加分配块的大小(例如,增加到以前大小的两倍)。