Чтобы работать с строкой, вам необходимо знать длину строки. Это делается с помощью 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, некоторые из нас любят сборку и не используют ничего другого.
Я бы сказал, что это выглядит как Unicode, но есть нечетное количество байтов (последний байт не имеет '00'). Это ошибка транскрипции? – lurker
Почему вы делаете программирование окон в сборке? Вы говорили с [Стивом Гибсоном] (https://www.grc.com/smgassembly.htm)? –