将字符附加到 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
增加分配块的大小(例如,增加到以前大小的两倍)。
刚开始学汇编,卡住了。
我在 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
增加分配块的大小(例如,增加到以前大小的两倍)。