Не получается вызвать sprintf
От: __kain Россия  
Дата: 06.12.05 20:39
Оценка:
Мне в программе надо вызвать примерно вот что: sprintf(buf,"%i.%i.%i %i:%i:%i"... А вот описать sprintf не получается... А ОЧЧЕНЬ неохота ручками форматированный вывод изобретать... Если у кого-то получалось, напишите, как описать сию функцию. Я пробовал
includelib msvcrt.lib
    extrn __imp__sprintf20:dword
        sprintf equ __imp__sprintf@20
не выходит. Хелп!
Re: Не получается вызвать sprintf
От: gear nuke  
Дата: 07.12.05 01:41
Оценка:
Здравствуйте, __kain, Вы писали:

__>Мне в программе надо вызвать примерно вот что: sprintf(buf,"%i.%i.%i %i:%i:%i"... А вот описать sprintf не получается... А ОЧЧЕНЬ неохота ручками форматированный вывод изобретать... Если у кого-то получалось, напишите, как описать сию функцию. Я пробовал

__>
__>includelib msvcrt.lib
__>    extrn __imp__sprintf20:dword
__>        sprintf equ __imp__sprintf@20
__>
не выходит. Хелп!


Чем не подходит wsprintf из user32?
Объявлена она, кстати, так:
wsprintfA PROTO C :DWORD,:VARARG
wsprintf equ <wsprintfA>
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 07.12.05 11:46
Оценка:
Здравствуйте, gear nuke.

Чем не подходит? Да мне в обще-то без разницы. Просто раньше на ассемблере не приходилось ничего писать. Спасибо, сегодня попробую.
Re[3]: Не получается вызвать sprintf
От: gear nuke  
Дата: 07.12.05 13:34
Оценка:
Здравствуйте, __kain, Вы писали:

__>Чем не подходит? Да мне в обще-то без разницы. Просто раньше на ассемблере не приходилось ничего писать. Спасибо, сегодня попробую.


Если подходит, тогда вот Вам примерчик:
    .586
    .model flat,stdcall
    option casemap:none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc

;--------------------------------------------------------------------------------
;creates string in .data section & returns pointer to it
;--------------------------------------------------------------------------------
$db macro   arg:vararg
LOCAL   data_ptr
.DATA
data_ptr    db arg
.CODE
exitm   <offset data_ptr>
endm

.code
start:

main proc
     local  buf [256]:byte

     invoke wsprintfA, addr buf, $db ("%i.%i.%i %i:%i:%i", 0), 1, 2, 3, 4, 5, 6

     .if eax
        invoke MessageBoxA, 0, addr buf, $db ("wsprintf test", 0), MB_OK 
     .endif

     invoke ExitProcess, eax

main endp

end start

Компилируется так:
ml /coff wsprintf.asm /link /subsystem:windows kernel32.lib user32.lib

Если будет ругаться на wsprintfA, добавте прототип
Автор: gear nuke
Дата: 07.12.05
.

CRT лучше не использовать — нужной версии msvcrt.dll может не быть в старых виндовсах.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 07.12.05 14:36
Оценка:
Здравствуйте, gear nuke.

Спасибо за пример!!! Правда не пойму, для какого это ассемблера? для MASM? У меня дока такая, которая может компилиться на всех видах ассемблера...
Re[5]: Не получается вызвать sprintf
От: gear nuke  
Дата: 07.12.05 15:51
Оценка:
Здравствуйте, __kain, Вы писали:

__>Спасибо за пример!!! Правда не пойму, для какого это ассемблера? для MASM?


Да, для масм. Я понял что Вам нужен он, по extrn __imp__sprintf20:dword

__>У меня дока такая, которая может компилиться на всех видах ассемблера...


На всех вряд ли диалекты сильно различаются. Или что за дока, я не совсем понял
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[6]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 07.12.05 17:53
Оценка:
Здравствуйте, gear nuke, Вы писали:

Дока у меня электронная — "Ассемблер для Unix, Dos, Windows". Выразился я немного неточно, там в .inc файлах различие есть, а в целом программы построены без специфических наворотов.

Кстати, компиль ругается: Syntax Error: PROTO.

P.S.
Компиль у меня ml.exe. Нашел я его в пакете с Visual Studio .NET 2003...
Re: Не получается вызвать sprintf
От: vvotan Россия  
Дата: 07.12.05 17:57
Оценка:
Здравствуйте, __kain, Вы писали:

__>Мне в программе надо вызвать примерно вот что: sprintf(buf,"%i.%i.%i %i:%i:%i"... А вот описать sprintf не получается... А ОЧЧЕНЬ неохота ручками форматированный вывод изобретать... Если у кого-то получалось, напишите, как описать сию функцию. Я пробовал


> __imp__sprintf@20

Хм, а откуда вот это взялось? sprintf ни разу ни stdcall.

Вот вполне рабочий пример.
.386
.model flat

 includelib kernel32.lib
 includelib msvcrt.lib

 extrn __imp__GetStdHandle@4:dword
 extrn __imp__WriteConsoleA@20:dword
 extrn __imp__ExitProcess@4:dword
 extrn __imp__sprintf:dword

 STD_OUTPUT_HANDLE equ -11

.data 
br dd ?
fstr db 'Tezt: %d %d',0
buf dd 10 dup(0)

.code
_start:
    push STD_OUTPUT_HANDLE
    call GetStdHandle
    push 10
    push 20
    push offset fstr
    push offset buf
    call __imp__sprintf
    add esp, 16
    push 0
    push offset br
    push 11
    push offset buf
    push eax
    call __imp__WriteConsoleA@20
    push 0
    call __imp__ExitProcess@4
end _start
--
Sergey Chadov

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 07.12.05 19:56
Оценка:
Здравствуйте, vvotan

Ура, заработало!!! Оч большое спасибо.... Если позволите, я задам еще 2 вопроса:
1)
add esp, 16
Это очистка стека после вызова процедуры?
2) Почему компилятор мне запрещает вызовы процедур и переход по меткам внутри процедур?
Re[3]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 07.12.05 19:58
Оценка:
(тоесть в процедурах, объявленных как extrn он разрешает вызов таких-же extrn процедру, но переходить по меткам и на описанные мной процедуры всеравно нельзя)
Re[3]: Не получается вызвать sprintf
От: vvotan Россия  
Дата: 07.12.05 21:04
Оценка:
Здравствуйте, __kain, Вы писали:

__>Здравствуйте, vvotan


__>Ура, заработало!!! Оч большое спасибо.... Если позволите,

Лучше будет на "ты"
__> я задам еще 2 вопроса:
__>1)
add esp, 16
Это очистка стека после вызова процедуры?

Да. sprintf использует соглашение о вызове cdecl, по которому очищать стек обязана вызывающая процедура.
__>2) Почему компилятор мне запрещает вызовы процедур и переход по меткам внутри процедур?
Ничего не понял. Приведи кусок кода.
--
Sergey Chadov

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Не получается вызвать sprintf
От: gear nuke  
Дата: 08.12.05 05:12
Оценка:
Здравствуйте, __kain, Вы писали:

__>Дока у меня электронная — "Ассемблер для Unix, Dos, Windows". Выразился я немного неточно, там в .inc файлах различие есть, а в целом программы построены без специфических наворотов.


По программированию под Win32 лучше Icazelion'а почитать, он для С программистов пишет, там и примеры есть. Ну а сам асм можно и по Зубкову изучать.

__>Кстати, компиль ругается: Syntax Error: PROTO.

__>Компиль у меня ml.exe. Нашел я его в пакете с Visual Studio .NET 2003...

У меня такой же, а что за полный текст ошибки-то? Вероятно проблемы с отсутствием хидеров Вам мешают, можно взять готорвые из дистрибутива hutch здесь. Компилятор там старый вроде, можно новый оставить. Или можно fasm там же посмотреть, с ним идут примеры. Это хороший (нет оверхеда в синтаксисе вроде offset) ассемблер, у Зубкова он не описан, но подробно документирован в отличие от других (на английском).

Вот как на нём может выглядеть использование CRT — описание таблицы импорта PE файла сразу в исходнике, никакие линкеры и либы не нужны

    format  pe

;;        mov ebp,esp
        push    read_mode
        push    source_name
        call    [fopen]
        test    eax, eax
        jz      not_found
        add     esp, 2*4
        xchg    eax, esi

@@:     push    0
        mov     edi, esp

        push    esi
        push    1
        push    1
        push    edi
        call    [fread]
        add     esp, 4*4
        test    eax, eax
        jz      close

        push    edi
        push    form
        call    [printf]
        add     esp, (2+1)*4

;;        mov esp,ebp
        jmp     @b

close:  push    esi
        call    [fclose]
        add     esp, (1+1)*4

exit:  ;; mov esp,ebp
        ret

not_found:
        push    error_message
        call    [printf]
        add     esp, (2+1)*4
        jmp     exit

error_message   db "coudn't open file `%s'.",0 
form            db "%s",0
read_mode       db "r",0
source_name     db "crt.asm",0


align 4
data import

        dd 0,0,0,rva kernel_name,rva kernel_table
        dd 0,0,0,rva msvcrt_name,rva msvcrt_table
        dd 0,0,0,0,0

;   2K needs this to load PE
kernel_table:   dd 0

msvcrt_table:
fclose      dd rva fclose$
fread       dd rva fread$
fopen       dd rva fopen$
printf      dd rva printf$
            dd 0    

kernel_name db 'KERNEL32.DLL',0
msvcrt_name db 'MSVCRT.DLL',0
fclose$     db 0,0,'fclose',0
fread$      db 0,0,'fread',0
fopen$      db 0,0,'fopen',0
printf$     db 0,0,'printf',0

end data

Но очень неудобно будет руками считать байты на стеке, лучше макросы всё же использовать типа invoke. Хотя, смотря чему учиться хотите win32 или asm
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[5]: Не получается вызвать sprintf
От: glyph  
Дата: 08.12.05 08:03
Оценка:
Здравствуйте, __kain, Вы писали:

__>Здравствуйте, gear nuke.


__>Спасибо за пример!!! Правда не пойму, для какого это ассемблера? для MASM? У меня дока такая, которая может компилиться на всех видах ассемблера...

fasm можно. впрочем, у masm32 от версии к версии изменений не много...
... << RSDN@Home 1.1.4 beta 3 rev. 193>>
Re[6]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 09.12.05 13:52
Оценка:
Странно, на 2 прмера выдает одну и туже ошибку: can't jump near of far label

.model flat
.data
.386
proc_1 proc
cmp eax, 6
je m1
jmp m2
m1:
; some code
m2:
; some code
ret
proc_1 endp
.code
....


.model flat
.data

proc_1 proc
...
ret
proc_1 endp

proc_2 proc
call proc_1
ret
proc_2 endp
.code
...
Re: Не получается вызвать sprintf
От: emusic Франция https://software.muzychenko.net/ru
Дата: 09.12.05 16:13
Оценка: +1
Здравствуйте, __kain, Вы писали:

__>Мне в программе надо вызвать примерно вот что: sprintf(buf,"%i.%i.%i %i:%i:%i"...


Можно дурацкий вопрос? Какой смысл писать на ассемблере код, нуждающийся в такой "тяжелой" сишной функции, как sprinf? Ладно бы это был какой-нибудь сверхбыстрый или сверхкомпактный код, а так...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 09.12.05 17:15
Оценка:
Здравствуйте, emusic, Вы писали:

E>Можно дурацкий вопрос? Какой смысл писать на ассемблере код, нуждающийся в такой "тяжелой" сишной функции, как sprinf? Ладно бы это был какой-нибудь сверхбыстрый или сверхкомпактный код, а так...


Ответ простой: необходимо сдать курсовую работу. Написанную на ассемблере
Re[7]: Не получается вызвать sprintf
От: gear nuke  
Дата: 10.12.05 07:34
Оценка:
Здравствуйте, __kain, Вы писали:

__>Странно, на 2 прмера выдает одну и туже ошибку: can't jump near of far label


__>.model flat
__>.data
__>.386
__>   proc_1 proc
__>      cmp eax, 6
__>      je m1
__>      jmp m2
__>   m1:
__>      ; some code
__>   m2:
__>      ; some code
__>      ret
__>   proc_1 endp
__>.code

Вполне логично — masm считает что выполнять данные нельзя. Поставте перед кодом директиву .code
Кстати, все предложенные здесь варианты такой ошибки не имеют.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[8]: Не получается вызвать sprintf
От: __kain Россия  
Дата: 11.12.05 10:17
Оценка:
Здравствуйте, gear nuke.

Спасибо, компилятор заткнулся =)
Re[2]: Не получается вызвать sprintf
От: vvotan Россия  
Дата: 13.12.05 08:58
Оценка:
Здравствуйте, emusic, Вы писали:

E>Здравствуйте, __kain, Вы писали:


__>>Мне в программе надо вызвать примерно вот что: sprintf(buf,"%i.%i.%i %i:%i:%i"...


E>Можно дурацкий вопрос? Какой смысл писать на ассемблере код, нуждающийся в такой "тяжелой" сишной функции, как sprinf? Ладно бы это был какой-нибудь сверхбыстрый или сверхкомпактный код, а так...


А если в сверхбыстро-сверхкомпактной программе где-нибудь в одном-двух местах или вообще для отладки надо что-нибудь напечатать, ты предлагаешь все на С переписывать? Не говоря уже о курсовых
--
Sergey Chadov

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.