FASM размещение данных в любом месте программы

Тема в разделе "WASM.ASSEMBLER", создана пользователем Y_Mur, 24 апр 2007.

  1. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Хочу определять данные, особенно текстовые строки по ходу программы, а не где нибудь в начале или в конце.
    Кривой штатный вариант фасма не устраивает, юзать чуждый философии фасма линкер - не радует, на форуме фасма (здесь и здесь) тоже ничего путного.
    Поэтому делаю так:
    Код (Text):
    1. .code
    2. ; здесь код программы
    3. macro MyData
    4. {szMyString1 db 'hello', 0}
    5. ; здесь дальше код программы
    6. macro MyData
    7. {MyData             ; объединение новых данных со старыми
    8. szMyString2 db 'Привет', 0}
    9. ; здесь дальше код программы
    10. .data
    11.  MyData ; А здесь собранные в кучу данные будут реально располагаться
    12. ...
    Нет ли более элегантного способа?

    И что-то не нашёл в мануале и примерах фасма возможности создания макрофункций, чтобы можно было писать типа
    .if FUNC(MessageBox, [hwnd], zSTR('Привет'), zSTR('Фасм'), MB_YESNO) == IDYES
    ...
    Или это тоже противоречит его филосифии?
     
  2. twgt

    twgt New Member

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    1.494
    Извините за оффтоп.
    Вот и твои посты клонироваться начали :), и в др темах тоже.
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    twgt
    Если бы это я клонировал;) - само получилось - я попробовал затереть этот странный клон (вишь Отредактированно) - а он затирается тоже только сразу в обоих экземплярах - прикольно :)))
     
  4. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    macro szText a*
    {
    local .next
    call .next
    DB a,0
    .next:
    }
    . . .
    push MB_OK
    szText 'Capt'
    szText 'Hi'
    push 0
    call [MessageBox]
     
  5. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Как вариант, не в .data, а в стек
     
  6. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    asmfan
    Дык я же сразу привёл линк, что этот кривой вариант, нарушающий работу предсказателя ret-ов меня не устраивает - именно с ним я и борюсь ;).
     
  7. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    Есть такой файлик kglobals.inc - он с помощью макросов собирает все данные в одном месте. Есть в исходниках fresh и KolibriOS (http://kolibrios.org/?p=SVN&kind=dir&loc=/kernel/trunk).
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    asmfan
    все же определять так строки не прикольно, точнее заталкивать адрес строки через call. как-то... не красиво чтоли. да и отлаживать потом такой код не в кайф: думаешь, что вызов подпрограммы, а хрен тебе..
     
  9. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Медленно это... В INTEL Manuals не рекомендуется.
     
  10. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Это всего лишь способ. Конечно мы загрязняем кэш, да отлаживать/дизассемблировать такое сложно, но это просто способ, для чего тогда в своё время был SMC да и обфускаторы. Принцип: код и данные/data/ - одно и то же, не я закладывал.
    /а вообще давно такая мысля вертится - не хранить некоторые константы как данные/immediates, а брать их из кода (т.е. адресовать код как данные)/
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    halyavin
    Спасибо посмотрел - тот же самый приём, только вместо "классического" макроса форма с fix \}

    asmfan
    Но одно дело аккуратно сложить их в конце кодового сегмента (так даже мастер leo
    поступает), хотя если кроме констант нужны инициализированные переменные (а мне они почти всегда нужны в достаточно большом количестве), то выигрыш весьма сомнительный. И совсем другое дело раскидывать их где попало захламляя код лишними переходами и тем более безвозвратными call-ами - для какого-нибудь дельфина сойдёт за третий сорт, но на FASMe - совсем не солидно (очень странно что вместо нормальной опции (хочешь включай не хочешь не надо) объединения одноимённых сегментов в Фасм включена кривая ...ax инклюда)
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    лучше сделать ченить вроде такого, если очень хочется мешать код и данные.
    Код (Text):
    1. push 0
    2. push 0
    3. jmp __continue
    4.  msg db 'Hello, World', 0
    5. __continue:
    6. push msg
    7. push 0
    8. call dword [MessageBoxA]
    и отлаживать удобно..
    Код (Text):
    1. 00401000 >/$ 6A 00          PUSH 0
    2. 00401002  |. 6A 00          PUSH 0
    3. 00401004  |. EB 0D          JMP SHORT test.00401013
    4. 00401006  |. 48 65 6C 6C 6F>ASCII "Hello, World",0
    5. 00401013  |> 68 06104000    PUSH test.00401006                       ; |Text = "Hello, World"
    6. 00401018  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
    7. 0040101A  |. FF15 3B204000  CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
     
  13. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Great
    Так конечно лучше чем у asmfan, но я хочу чтобы запись вида
    Код (Text):
    1. invoke MessageBox, [hwnd], zSTR('Привет'), zSTR('Фасм'), MB_OK
    сама себя нормально "рассортировывала" - данные к данным - код к коду.
    На масме это элементарно, а на фасме у меня пока не получается.
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Y_Mur
    в смысле чтобы данные были вместе с кодом, или чтобы оно само выносило строчки в секцию данных?
     
  15. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Great
    На масме делаю так:
    Код (Text):
    1. ; Строка с завершающим нулём
    2. zSTR MACRO P1, P2
    3. LOCAL zSTRname
    4.   IFB <P2>; Строка без имени
    5.     .data
    6.       zSTRname db P1, 0
    7.     .code
    8.     EXITM <offset zSTRname>
    9.   ELSE    ; Строка с именем
    10.     .data
    11.        P1 db P2, 0
    12.     .code
    13.     EXITM <offset P1>
    14.   ENDIF
    15. ENDM
    На фасме из этого получится сегментная каша, юзать чуждый фасму (и не входящий в его комплект) линкер ради исправления этого не хочу (другое дело когда нужно фасм с сями состыковать, там COFF самое оно). А где в результате будут строки - в конце секции кода или в своём родном сегменте .data не принципиально, главное чтобы они сгрупировались и через них прыгать не нужно было (чехарда хорошая игра, но не в программировании ;).
     
  16. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Y_Mur
    Посмотри библиотеку S_T_A_S_'a, там то, что ты хочешь, правда, под старые версии фасма. Идею поймёшь, сможешь портировать, улучшить. Главное - оно работало.
     
  17. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    IceStudent
    Спасибо - буду разбираться :)
     
  18. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    пока такое реализовать, достаточно тяжело на макросах фасма, так как философии фасма противоречит возможность макросов возвращать результаты...

    Фасмлиб вера не даёт использовать?
     
  19. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    dead_body
    Но ведь MessageBox(0,'Hi',0,0) можно :)
     
  20. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Да с возвратами результатов из функций придётся капитально помедитировать ;)

    А пока исправил в win32ax.inc и win32axp.inc неадекватные конструкци:
    Код (Text):
    1.    call ..continue
    2.    db value,0
    3.    ..continue:
    на:
    Код (Text):
    1.     macro __data
    2.     \\{ __data
    3.         ..zstr db value, 0
    4.     \\}
    5.     push ..zstr
    и сохранил как win32axm.inc win32axpm.inc (m -модифицированные)

    Теперь стандартный пример:
    Код (Text):
    1. include 'win32axm.inc'
    2. .code
    3.   start:
    4.     invoke  MessageBox, HWND_DESKTOP, 'Привет!', 'Я изучаю FASM', MB_OK
    5.     invoke  ExitProcess, 0
    6. .end start
    генерирует нормальный код :))
    Здесь строки аккуратно складываются в конце кодового сегмента

    Код (Text):
    1. include 'win32axm.inc'
    2. .code
    3.   start:
    4.     invoke  MessageBox, HWND_DESKTOP, 'Привет!', 'Я изучаю FASM', MB_OK
    5.     invoke  ExitProcess, 0
    6. .data
    7. .end start
    Здесь данные попадут в сегмент инницализированных данных.

    А если перед .end очень нужно поместить неинициализированный сегмент, то чтобы он не "испортился", то писать так:
    Код (Text):
    1. include 'win32axm.inc'
    2. .code
    3.   start:
    4.     invoke  MessageBox, HWND_DESKTOP, 'Привет!', 'Я изучаю FASM', MB_OK
    5.     invoke  ExitProcess, 0
    6. .data
    7.   MyVar dd 10
    8.   SetData   ; <-- разместить строки здесь
    9. section '.bss' data readable writeable
    10.   szBuffer rb 1024
    11. .end start
    Кроме того в любом месте кода можно определять данные, которые попадут в блок SetData
    Код (Text):
    1. include 'win32axm.inc'
    2. .code
    3.   start:
    4.     macro __data {__data
    5.        RealVar1 dd 10.5
    6.        RealVar2 dq 17.5 }
    7.     fld  [RealVar2]
    8.     fistp [MyVar]
    9.     invoke  MessageBox, HWND_DESKTOP, 'Привет!', 'Я изучаю FASM', MB_OK
    10.     invoke  ExitProcess, 0
    11. .data
    12.   MyVar dd 10
    13.   SetData   ; <-- разместить строки здесь
    14. section '.bss' data readable writeable
    15.   szBuffer rb 1024
    16. .end start
    Здесь аттач не удачный см.#26