2013-08-11 2 views
0

Я не очень хорошо разбираюсь в сборке, мне просто нужно это писать в сборке в любом случае, вот что я пытаюсь сделать. (Я использую masm32)Чтение Hex as String

.data 
     Msg db 31h, 00h, 32h, 00h, 33h ;convert this to string which "123" 

    .code 

    start: 

     invoke MessageBox, 0, addr Msg, 0, 0 
     call ExitProcess 
    end start 

Как вы можете видеть каждый символ или байт отделяется с нулевым байтом, он может показывать только один байт, «1» вместо «123»

Если только Я могу объединить каждый читаемый байт, пока он не достигнет конца строки.

mov ebx, offset Msg 
mov ecx, ebx 
add ebx, 2 
invoke lstrcat, ebx, ecx 

Может быть, добавить петлю и я просто не знаю, лучший способ кодировать его, или если у вас есть лучшее решение, которое вы можете поделиться.

+0

Я бы сказал, что это выглядит как Unicode, но есть нечетное количество байтов (последний байт не имеет '00'). Это ошибка транскрипции? – lurker

+0

Почему вы делаете программирование окон в сборке? Вы говорили с [Стивом Гибсоном] (https://www.grc.com/smgassembly.htm)? –

ответ

0

Чтобы работать с строкой, вам необходимо знать длину строки. Это делается с помощью 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, некоторые из нас любят сборку и не используют ничего другого.