为了处理字符串,您需要知道字符串的长度。这是通过使用 NULL 终止字符串来完成的。不将字符串长度作为参数的函数将查找 00H,并将字符串打印到它之前,这就是 MessageBox 正在做的事情,打印“1”并看到下一个字符是 00h,停止打印。
在您的情况下,如果字符串末尾没有 NULL 终止符,我们可以在汇编时使用符号“$”获取字符串长度,该符号是位置计数器的当前值。
Msg db 31h, 00h, 32h, 00h, 33h ;convert this to string which "123"
Msg_Len equ $ - Msg
这意味着,取 $ 的地址并减去 Msg 的地址,并将 Msg_Len 替换为该值。
include masm32rt.inc
.data
Msg db 31h, 00h, 32h, 00h, 33h ;convert this to string which "123"
Msg_Len equ $ - Msg
.data?
Msg_New db Msg_Len + 1 dup (?)
.code
start:
xor ecx, ecx ; index into source array
xor edx, edx ; index into dest array
lea esi, Msg
lea edi, Msg_New
ConvertIt:
mov al, byte ptr[esi + ecx] ; get byte at pointer + index
cmp al, 0 ; is it a 0?
jne @F ; no, add it to dest array
inc ecx ; yes, increase source index
jmp CheckForEnd ; check to see if at end
@@:
mov byte ptr [edi + edx], al; add byte to dest array
inc ecx ; increase both indexes
inc edx ;
CheckForEnd:
cmp ecx, Msg_Len ; check for end - if ecx == Msg_Len we are done
jne ConvertIt ; if ecx != Msg_Len, continue loop
mov byte ptr [edi + edx], 0 ; don't forget to NULL terminate dest string
invoke MessageBox, HWND_DESKTOP, offset Msg_New, NULL, MB_OK
invoke ExitProcess, 0
end start
这可以通过更少的代码和“就地”“转换”字符串来完成,但这超出了这里的范围。
@Nik,我们中的一些人喜欢组装并且不使用其他任何东西。