文字列を操作するには、文字列の長さを知る必要があります。これは、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、私たちの中にはアセンブリが大好きで、他に何も使用しない人もいます。