Преобразование чисел в строку...

Тема в разделе "WASM.BEGINNERS", создана пользователем Slavian, 4 авг 2005.

  1. Slavian

    Slavian New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2005
    Сообщения:
    2
    На C я делал с помощью _itoa , но в масме её не нашёл поэтому начал писать сам...

    вот что получилось:

    CreateString proc Number:lol: WORD



    push ebx

    add esp,8

    push Number

    pop ebx

    xor ecx,ecx



    Loop1:

    mov eax,ebx

    cmp ecx,4

    jz Loop2

    cmp ecx,0

    jz ECX0

    cmp ecx,1

    jz ECX1

    cmp ecx,2

    jz ECX2

    jmp ECX3



    ECX0:

    shl eax,28

    shr eax,28

    add eax,48d

    mov edx,eax

    jmp INC_ECX



    ECX1:

    shl eax,24

    shr eax,28

    add eax,48d

    mov dh,al

    jmp INC_ECX



    ECX2:

    shl eax,20

    shr eax,28

    add eax,48d

    rol edx,16

    mov dh,al

    jmp INC_ECX



    ECX3:

    shl eax,16

    shr eax,28

    add eax,48d

    mov dl,al

    rol edx,16



    INC_ECX:

    inc ecx

    jmp Loop1



    Loop2:

    pop ebx

    ret



    CreateString endp



    конечно, надо доделать, но по сути правильно...

    вопрос в другом...

    вот есть у меня

    EDX=30303030h это по ASCII : "0000"

    КАК мне это загнать в строку

    если сделать

    buffer db 10 dup(0)

    то не работает...

    как мне добавить в строку? или добавить "0" в конец??
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860


    mov dword ptr [buffer], edx

    mov byte ptr [buffer+4], 0
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    если есть буфер

    buffer db 10 dup(0)

    то EDX=30303030h сохраняется в буфер так:

    mov dword ptr[buffer],edx.

    Причем младший байт edx(dl) будет прописан по младшему адресу буфера. Т.е. например если edx = 30313233h, ecx = 64636261h то при

    mov dword ptr[buffer],edx

    mov dword ptr[buffer+4],eсx

    в буфер будет записана строка "3210abcd".
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Код (Text):
    1. ;===================================================================== ==============
    2. ;   Процедура перевода dword - числа в decimal-строку. Выходная строка
    3. ;   помещается в буфер lpOutString: '-1234567890',0
    4. ;   Возвращаемое значение: нет
    5.  
    6. .data
    7.     r_divisor           dd  -858993459
    8. .code
    9.  
    10. _dwtostr proc dwDword:DWORD, lpOutString:DWORD
    11.     option  prologue : none
    12.     option  epilogue : none
    13.  
    14.     push    esi
    15.     push    edi
    16.     mov     edi,[esp+16]                ;lpOutString
    17.     mov     esi,[esp+12]                ;dwDword
    18.     cmp     esi,0
    19.     jg      _loop
    20.     jz      _zero
    21.     neg     esi
    22.     mov     byte ptr[edi],2Dh
    23.     inc     edi
    24.     inc     dword ptr[esp+16]           ;lpOutString
    25.  
    26. align 16    
    27. _loop:
    28.     mov     eax,esi
    29.     mul     r_divisor
    30.     shr     edx,3
    31.     mov     ecx,edx
    32.     lea     ecx,[ecx*4+ecx]
    33.     add     ecx,ecx
    34.     neg     ecx
    35.     add     ecx,esi
    36.     mov     byte ptr[edi],30h
    37.     or      [edi],cl
    38.     mov     esi,edx
    39.     test    edx,edx
    40.     lea     edi,[edi+1]
    41.     jnz     _loop
    42.  @@:
    43.     mov     byte ptr[edi],0
    44.     mov     esi,[esp+16]
    45. align 16
    46.  @@:
    47.     dec     edi
    48.     mov     al,[esi]
    49.     mov     dl,[edi]
    50.     mov     [edi],al
    51.     mov     [esi],dl
    52.     inc     esi
    53.     cmp     esi,edi
    54.     jl      @B
    55.     pop     edi
    56.     pop     esi
    57.     retn    8
    58. _zero:
    59.     mov     word ptr[edi],30h
    60.     pop     edi
    61.     pop     esi
    62.     retn    8
    63.     option  prologue : prologuedef
    64.     option  epilogue : epiloguedef
    65. _dwtostr endp
     
  5. Slavian

    Slavian New Member

    Публикаций:
    0
    Регистрация:
    4 авг 2005
    Сообщения:
    2
    спасибо, конечно,

    но что элементарно означата

    mov dword ptr [],eax ?

    под масм работает?

    а почему вот тут:

    mov dword ptr [buffer], edx

    mov byte ptr [buffer+4], 0

    потом только [buffer+4] ведь edx 32-бита





    а что в последнем примере означатает:

    align 17 ?

    @@ ?

    option prologue?

    option epilogue?

    почему именно

    mov edi,[esp+16]

    почему EDI, и почему esp+16



    а не допустим комбинация

    push dwDword

    pop edi



    а что значит retn 8



    ??
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257




    Это значит: записать дворд (4 байта), содержащийся в eax, в 4 ячейки, начинающиеся с адреса, указанного внутри квадратных скобок. В каждую ячейку помещается 1 байт (или 8 бит).



    mov dword ptr [buffer],eax

    ;buffer - адрес, с которого начинается твой буфер. Например 403000h

    ;биты 0-7 (это al) помещаются по адресу 403000h

    ;биты 8-15 (это ah) помещаются по адресу 403001h

    ;биты 16-23 помещаются по адресу 403002h

    ;биты 24-31 помещаются по адресу 403003h







    здесь также 32 бита edx (или 4 байта) записываются в 4 ячейки размером 1 байт (8 бит). О том, что записываться будет 4 байта, указывает приставка dword.

    После этого записывается 0 в одну ячейку (1 байт). Это указывается приставкой byte

    Т.е. сколько будет записываться и в сколько ячеек, указывается в команде при помощи приставки dword/byte ptr.



    а что в последнем примере означатает:

    align 17 ?

    @@ ?

    option prologue?

    option epilogue?




    align 16 - это указание компилятору, что инструкции, следующие после этой директивы, нужно расположить по адресу, кратному 16.

    @@ - это метка. Переход на эту метку осуществляется так:

    jmp @B или jmp @F. В первом случае переход будет на ближайшую метку @@, находящуюся перед командой jmp @B, во втором случае - на ближайшую метку @@, находящуюся после jmp @F. Т.е. @B - это Backward, @F - Forward.



    option prologue/option epilogue - это директивы для компилятора, тебе они не нужны.







    Процедура вызывается так:
    Код (Text):
    1. push    offset buffer     ;в вершине стека [esp] - адрес буфера
    2. mov     eax,1234567
    3. push    eax               ;в [esp]- число для преобразования,
    4.                           ;адрес буфера переместился в [esp+4]
    5. call    _dwtostr          ;в [esp]- адрес, куда возвращаться из функции
    6.                           ;число для преобразования переместилось в [esp+4]
    7.                           ;буфер переместился в [esp+8]




    и когда начинается выполнение функции преобразования, первые две команды в ней - это команды сохранения регистров esi/edi.

    push esi

    push edi

    каждая команда ложит регистр в вершину стека, при этом проталкивая уже лежащие в стеке параметры каждый раз на 4 байта. Т.е. push esi и push edi сдвинут вершину стека на 8 байт. При этом параметры, которые передавались в функцию, тоже сместятся на 8 байт, и будут находиться:

    число для преобразования - в [esp+12]

    адрес буфера для формирования выходной строки - в [esp+16]

    поэтому и mov edi,dword ptr[esp+16] - в edi загружается адрес буфера.



    А вообще, на сайте есть для начинающих статьи о низкоуровневом программировании, возьми и почитай их. Там всё разжёвано подробно. С несложными примерчиками.