CPUID

Тема в разделе "WASM.BEGINNERS", создана пользователем Shoorup, 8 сен 2008.

  1. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    А за счет чего она станет меньше? Можно на пальцах :) В секции днанных например я размещу 10 байт данных или в секции кода размещу 10 байт данных. Как будет это влиять на размер?
    А за счет чего она станет медленней?

    (прошу прощения за совсем детские вопросы, просто ветки ниже BEGINNERS ничего нет)
     
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    Shoorup
    Давай на практике -- создай в секции .idata переменную X db 10000 dup (?) скомпилируй программу и посмотри ее размер, а теперь создай в секции .data переменную X db 10000 dup (0) скомпилируй программу и посмотри ее размер. Если при компиляции не используется ключ /ALIGN -- секции имеют размер кратный 512 байтам. Если у тебя всего две секции: кода и данных, то, в целом, размер программы 512+512=1024 байт хотя, данных всего на 10 байт. Теперь размещаем эти же данные в секцию кода, и размер уже не 1024, а всего 512 байт. Программа с записываемыми данными в секции работает медленее потому, что при записи в эти переменные будут происходить сброс кэша и сброс механизма предсказания переходов, это тебе лучше всего leo или Y_Mur смогут объяснить
     
  3. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    Mikl___ с размером понял. А вот со скоростью... может еще рановато заострять на этом внимание?
     
  4. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Про скорость я читал в Intel Software Optimization Reference (надеюсь правильно написАл).
     
  5. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    Продолжаю копать дальше. Чем дальше копаю тем более непонятно.
    1. почему неинициализированные данные
    Код (Text):
    1. .data?
    2. mesbox_text db 600h dup(?)
    у меня в коде:
    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. .data?
    4. m db 10000h dup(?)
    5. .code
    6. start:  
    7. nop
    8. end start
    отображаются в дампе, а у Mikl___а в коде? Чую ну очень идиотский вопрос, ну уж простите - учусь

    До конца не понимаю механизма работы. Как в отладчике работает понимаю, но сам бы не додумался и не повторил бы...
    Как это работает:
    Код (Text):
    1. mov edi,offset mesbox_text
    2. mov esi,offset buffer
    3. mov [esi+11],ebx
    4. mov [esi+15],edx
    5. mov [esi+19],ecx
    Напишите пожалуйста коменты к этим строчкам и вызываемой процедуре StringOut.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Shoorup
    Неинициализированные данные (в данном случае под неинициализированными данными понимаются те, при указании которых ставится знак "?") могут как отображаться, так и не отображаться в дампе, находясь в любой секции.
    1) Если неинициализированные данные находятся в конце секции (не важно, какой), то самым логичным поведением компилятора было бы увеличение атрибута секции VirtualSize при неизменном атрибуте SizeOfRawData. Т.о. на размер образа на диске такие неинициализированные данные не повлияют, но при загрузке образа в память, необходимый объём памяти будет выделен.
    2) Если Вы вдруг захотите после инициализированных данных впихнуть инициализированные. Т.е примерно так:
    section '.data' data readable writeable
    uninitData db 1000 dup ?
    initData db 'ю'
    , то компилятор будет вынужден заполнить промежуток реально существующими данными. И тогда такие "неинициализированные данные" на самом деле будут находиться в образе на диске. И инициализированы они будут нулями. Опять таки это независимо от того, в какой секции они находятся.

    Всё выше сказанное относится к fasm, но может быть перенесено и на masm с учётом того, что masm несколько ограничивает программисту свободу выбора. ИМХО fasm демонстрирует более истинную картину.
     
  7. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    Shoorup
    Статьи Агнера Фога на WASM.RU читай, от программ на ассемблере (ассемблерных вставок) требуется либо минимальный размер либо запредельная скорость. И то, и другое совместить редко удается -- обычно сосредотачиваются на чем то одном.
     
  8. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Код (Text):
    1. StringOut       proc
    2. a1:     lodsb ;загружаем символ из [esi] в al и увеличиваем esi
    3.         or al,al ; если al равен 0
    4.         jz a2 ; то выход
    5.         stosb ;копируем символ в [edi] и увеличиваем edi
    6.         loop a1 ;уменьшаем ecx, если не равен 0, то повторяем итерацию
    7. a2:     retn
    8. StringOut       endp
    Эта процедура копирует нульзавершённую строку из [esi] в [edi] длиной не более чем ecx. Некий аналог lstrcpy из kernel32.dll.
     
  9. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    Интерестно с loop получается:) в счетчике лежит огромное число. А почему тут не jmp a1?
     
  10. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Shoorup
    имхо, вобще что-то не то...
    наверно надо что-то вроде
    Код (Text):
    1. LODSB
    2. STOSB
    3. TEST AL, AL
    4. LOOPNZ a1
     
  11. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    K10 ноль занесешь тогда.
    LODSB; загружаем
    STOSB; копируем
    TEST AL, AL; проверяем
    LOOPNZ a1; переходим если не ноль
    А если ноль то мы его занесем и выйдем из процедуры. Или я не правильно понял?
     
  12. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Shoorup
    Ага, завершающий ноль же тоже нужен...
    Ну и в ECX максимальный размер.
    Либо можно немного переделать и по ЕСХ определять количество скопированных байт если нужно, но тогда максимального размера не будет.
     
  13. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    Я так понимаю, что все строки выводятся в мессбокс. А как происходит переход на следующую строку?
    Частоту процессора определяют по rdtsc? Или я опять не туда смотрю?
     
  14. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    db 0Ah
    Там просто замеряется сколько тактов пройдёт за 1000 миллисекунд (герц - это количество тактов в секунду, в секунде 1000 миллисекунд).
    Код (Text):
    1. mov TimerLo,eax
    2. mov TimerHi,edx
    3. push 1000                     ; DelayTime=1000
    4. call _imp__Sleep@4         ; Sleep(DelayTime);
    5. rdtsc
    6. sub eax,TimerLo
    7. sbb edx,TimerHi
    8. mov TimerLo,eax
    9. mov TimerHi,edx
     
  15. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    Не могу понять почему в один и тот же выделенный размер (как мне кажется) компилятор отказывается заносить содержимое регистров?
    Вот так:
    Код (Text):
    1. .data
    2. CPU_Vender dd 3 dup(?)
    3. String_null db 0
    4. .code
    5. start:
    6. ...
    7. mov CPU_Vender, ebx
    8. mov CPU_Vender+4, edx
    9. mov CPU_Vender+8, ecx
    нормуль все, но если пытаюсь поменять
    CPU_Vender dd 3 dup(?) на CPU_Vender db 12 dup(?) , компилятор почему то ругается на 3 строчки с movами. Почему?

    В принципе понимаю, что для строчки достаточно 12 байт. Так dd 3 dup(?) создаю 3 раза по 4 байта (двойному слову), и так db 12 dup(?) создаю 12 байт по байту. Так какая разница как я выделил память?
     
  16. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    Shoorup
    Если CPU_Vender db 12 dup(?)
    тогда должно быть
    Код (Text):
    1. mov dword ptr CPU_Vender, ebx
    2. mov dword ptr CPU_Vender+4, edx
    3. mov dword ptr CPU_Vender+8, ecx
    :)
     
  17. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    Как всегда спасибо Mikl___:) Единственное для себя не уяснил один момент - или где-то не дочитал или нет нигде такого: есть ли раличие в хранении данных в памяти? Запишу я слово в память или 2 байта - есть ли разница?
     
  18. _Aspire

    _Aspire New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2008
    Сообщения:
    62
    Shoorup
    Канешна есть. Почитай про big endian && little endian
     
  19. Shoorup

    Shoorup New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2007
    Сообщения:
    109
    Всеравно не очень догоняю... уж не бейте за "жирафа"...
    Получается для х86 идет little-endian или "от младшего к старшему". Я выделяю и в первом и во втором случае место 12 байт. Процессор будет заносить содержимое регистров в эту область по "правилу от младшего к старшему" Какая разница как я выделил память? Почему во втором случае мне нужно переопределять dword ptr ?
     
  20. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    Shoorup
    Пример из жизни -- Леонид Ильич Брежнев, с одной стороны, генеральный секретарь, с другой --папа, с третьей -- Лёня. Можно звать и так, и так, но папа -- он только для Галины Брежневой, а генеральный секретарь для всех остальных. Всё зависит от контекста. Переменная обявленная размером 4 байта для всех будет dword, а вот регистр AL может занести свои данные в любой из четырех байтов этой переменной обращаясь через byte ptr