Изменение значения ранее объявленной переменной

Тема в разделе "WASM.BEGINNERS", создана пользователем Domian, 23 окт 2006.

  1. Domian

    Domian New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2006
    Сообщения:
    7
    Впервые на этом форуме. У меня есть одна проблема, которую ОЧЕНЬ надо решить. у меня не получается, может кто-нибудь что-нибудь подскажет. Итак, вопрос: как на этапе компиляции программы поместить смещение процедуры в зарезервированную ранее переменную (не при резервировании переменной, а позже). Пробовал помещать в эту переменную произвольное число - все работает (она получает новое значение), а вот смещение процедуры - не получается (переменная обнуляется). Код прилагаю. Спасибо.

    Код (Text):
    1. .DATA
    2. var dd  1   ;произвольное значение
    3. .
    4. .
    5. @cur = $
    6. ORG offset var
    7.     dd  3   ;здесь все работает (var получает значение 3)
    8. ORG @cur
    9. .
    10. .
    11. @cur = $
    12. ORG offset var
    13.     dd  offset Procedure    ;а здесь вместо смещения процедуры помещается 0
    14. ORG @cur
    15.  
    16. .CODE
    17. Procedure   proc
    18.  
    19.     ret
    20. Procedure   endp
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    FuncPtr dd offset Func
    ...
    Func proc

    Func endp
     
  3. Domian

    Domian New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2006
    Сообщения:
    7
    Я же сказал, смещение в переменную мне надо загрузить не во время ее создания, а позже (в другом месте кода).
     
  4. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    IceStudent
    Так ему не при резервировании нужно адрес вписать, а позже.

    Domian
    Прямого пути не вижу.
     
  5. Domian

    Domian New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2006
    Сообщения:
    7
    Может есть какой-нибудь кривой путь? Я пробовал через локальные макропеременные - с ними прога вообще не линкуется. Самое интересное, что в листинге ясно видно, что смещение заносится по нужному адресу. Но при запуске выдается ноль. Что за парадокс?
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Domian
    А.. Понял. Тебе надо проинициализировать var позже, чем объявить, но в процессе компиляции?

    Код (Text):
    1. var dd FuncPtr
    2. ...
    3. FuncPtr = offset Func
    4. ...
    5. Func proc
    6. Func endp
    Оно?

    В противном случае на ум приходит только фасм (директива store).
     
  7. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Domian
    Пожалуйста:
    Код (Text):
    1. @cur = $
    2. ORG offset var
    3.     dd offset Procedure-code_start+org_code_start
    4. ORG @cur
    5. ; ***
    6. .CODE
    7. org_code_start = 401000h
    8. code_start:
    9. ; ***
    10. Procedure PROC
    11. ret
    12. Procedure ENDP
    Значение для org_code_start я вытащил из отладчика. Оно зависит от порядка секций и сегментов в обьектниках.
     
  8. Domian

    Domian New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2006
    Сообщения:
    7
    IceStudent: Ты понял меня совершенно правильно.

    Прочитал оба ответа, завтра попробую.
     
  9. Domian

    Domian New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2006
    Сообщения:
    7
    Вариант от IceStudent не прошел. Насколько я понял, FuncPtr в примере - это макропеременная. При компиляции выдается ошибка: fatal error LNK1190: invalid fixup found, type 0x0001 (недопустимая адресная запись, тип 0x0001).

    Вариант от Quantum.
    1) Хотелось бы узнать как это работает, а это работает. Если можно небольшое пояснение, особенно насчет числа 401000h (какой смысл оно несет)?
    2) Правильное смещение получается только тогда, когда метка входа code_start стоит в самом начале сегмента кода (т.е. перед ней вообще ничего не должно быть), а процедура описана ПОСЛЕ точки входа. Если хотя бы одна процедура описана ДО точки входа, правильного результата не получается.
    3)По условиям моей задачи, я не могу знать как будет называться точка входа (проект будет работать в разных программах и не факт, что она будет называться именно так). Есть ли способ узнать значение точки входа в обход ее имени?
     
  10. Demon666

    Demon666 New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    99
    .data
    data_metka dd 0

    .code
    Mov edi,metka
    Mov data_metka,edi

    ;----------
    metka LABEL PROC
    Procedure PROC
    ret
    Procedure ENDP

    P. S.
    Хм…! Не знаю ответы или вопрос меня ввел(и) в заблуждение, но может, поможет?
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Domian
    Да, есть такое. Измени "=", на "equ". Будет работать.
     
  12. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Domian
    Это VA адрес данной стартовой метки в сегменте кода.

    Она может стоять и в другом месте, но тогда без отладчика получить VA этой метки будет очень сложно.

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

    Поставить такую метку в начало сегмента кода обычно труда не составляет. Т.к. секция кода обычно идёт первой в адресном пространстве экзешника (сразу после заголовка), адрес VA этой метки легко посчитать - это будет 401000h.
     
  13. Demon666

    Demon666 New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    99
    IceStudent
    Угу!

    P. S.
    Альтернатива
    .data
    data_metka dd metka

    .code
    metka LABEL PROC
    Procedure PROC
    ret
    Procedure ENDP
     
  14. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Demon666
    Это всё равно что мой первый пост, который ему не подошёл.
     
  15. Demon666

    Demon666 New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    99
    IceStudent
    Не согласен!

    Код (Text):
    1. var dd FuncPtr
    2. ...
    3. FuncPtr equ offset Func
    4. ...
    5. Func proc
    6. Func endp
    Этот код запишет в var адрес процедуры Func

    Код (Text):
    1. .data
    2. data_metka dd metka
    3.  
    4. .code
    5. metka LABEL PROC
    6. Procedure PROC
    7. ret
    8. Procedure ENDP
    Этот код идентичен приведенному коду выше и сделает то же самое! Запишет в data_metka адрес процедуры Procedure

    P. S.
    Давай каждый из нас останется при своем мнении, а тот, у кого будет такая же проблема с сабжем, увидит, кто был прав.
     
  16. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Ну и в чём здесь разница?
     
  17. Demon666

    Demon666 New Member

    Публикаций:
    0
    Регистрация:
    19 май 2006
    Сообщения:
    99
    IceStudent
    Твой первый пост, который ему не подошел:
    Код (Text):
    1. FuncPtr dd offset Func
    2. ...
    3. Func proc
    4.  
    5. Func endp
    он согласился что подойдет второй но во втором была естественно у него ошибка!

    Отличие первого от третьего нет строки FuncPtr equ offset Func

    P. S.
    Твой третий и мой последний выдают одинаковый результат.
     
  18. Domian

    Domian New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2006
    Сообщения:
    7
    Вы тут уж поссориться успели, пока меня небыло.

    Demon666
    Mov edi,metka
    Mov data_metka,edi

    Это изменение значения переменной во время исполнения программы, а мне надо во время компиляции. К тому же можно написать проще:

    mov data_metka, metka

    Так что это не подходит.

    IceStudent
    EQU работает, но в моем случае не совсем подходит. Дело в том, что в моем проекте переменная - это поле в структуре. И в различных экземплярах этой структуры должны храниться смещения разных процедур (в зависимости от определенных условий), а макропеременная FuncPtr получает последнее определенное для нее значение (и все экземпляры структуры тоже). По той же причине не подходит вариант из поста #13.

    Quantum
    Твой вариант подходит лучше всего. Учел замечание насчет метки в начале сегмента кода. Все получилось. Но возникла другая проблема. Как я уже сказал, в моем проекте переменная - это поле в структуре. И если эту структуру включить в другую структуру, то смещение в нее автоматически не переходит. Я предполагаю, что смещение в первую структуру загружается не во время трансляции, а во время компоновки программы, когда вторая структура уже создана и естественно не меняется. Я, наверное совсем вас всех запутал.

    У меня попутный вопрос: можно ли проверить значение переменной (уже зарезервированной и возможно инициализированной) на этапе трансляции программы для построения блока условной компиляции?
     
  19. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Domian
    А нельзя в секции данных обьявлять эту структуру просто как массив байт, а потом обращаться к ней через mystruct PTR или типа того?
    Код (Text):
    1. .DATA
    2. mystruct_instance db mystruct_size dup (?) ; или SIZEOF mystruct
    3.  
    4. .CODE
    5. ; тут загружаем в неё по нужному смещению метку процедуры как для обычной переменной.
    6.  
    7. ; а тут для обращения к mystruct_instance как ко структуре (хоть со вложенной структурой)
    8. ; используем mystruct PTR
    9. mov eax,(mystruct PTR [mystruct_instance]).some_field
    10.  
    11. ; или так:
    12. mov eax,[mystruct_instance + mystruct.some_field]
    Тем не менее, для таких специфических издевательств над ассемблером больше подходит фасм. Это также относится ко второму вопросу.
     
  20. dead_body

    dead_body wasm.ru

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