Вопрос про максимальную длину машинной команды

Тема в разделе "WASM.BEGINNERS", создана пользователем Scr1pt_, 22 мар 2007.

  1. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    держи :)

    mov dword ptr [eax + eax + 78563412h], 78563412h

    С7 84 00 12 34 56 78 12 34 56 78
    [opcode] [mod] [sib] [displ] [imm]

    Scr1pt_
    покажи пример инструкции, которая больше 15 байт (естественно, не учитывая повторяющиеся префиксы).
     
  2. Scr1pt_

    Scr1pt_ New Member

    Публикаций:
    0
    Регистрация:
    14 мар 2007
    Сообщения:
    34
    Извиняюсь, ещё не дочитал.
    Просто как всегда лезу впереди паровоза. Натура такая :)

    2Ustus : Не подскажешь, где можно слить упомянутые тобой мануалы?
     
  3. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    rmn
    тогда код операции только 1 байт, у двухбайтовых кодов (0F xx и у FPU) вроде нету таких команд.
     
  5. Scr1pt_

    Scr1pt_ New Member

    Публикаций:
    0
    Регистрация:
    14 мар 2007
    Сообщения:
    34
    Я новенький :) За линки сенкс.
     
  6. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Scr1pt_
    опкод может быть 3 байта, причем в некоторых инструкциях байты опкода идут не по порядку (в mmx для amd64 третий байт опкода идет после modr/m и sib).

    ---

    Допустим, что мы в 32-х разрядном режиме и у нас закодирована инструкция
    (а также со смещением (dword) и непосредственным операндом(dword))

    Во-первых, если присутствует префикс 66h, то он повлияет на размер непосредственног операнда - он уже будет не 4 байта, а 2.

    Во-вторых, если присутствует префикс изменения размера адреса, то он повлияет на размер смещения (оно также станет 2 байта, вместо 4-х) и в инструкции пропадет байт sib (так как перейдем в 16-ти разрядный режим, где этого байта вообще нет).

    В-третьих, если память не изменяет, префикс lock можно использовать только с ограниченным набором инструкций, иначе получишь #UD (а может это здесь и не к месту :)).

    так что, добавление к инструкции префиксов 66h и 67h увеличит ее размер на 2 и одновременно уменьшит на 5.
     
  7. PaCHER

    PaCHER New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    852
    Учись поиском пользоватся.
     
  8. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Не обязательно. Если бит D/B в дескрпиторе кода сброшен в 0, то префикс замены размера адреса и замены размера операнда наоборот "увеличат" размер непосредственного смещения и операнда -- он будет четыре байта вместо двух.
     
  9. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Mika0x65
     
  10. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Прошу прощения, был невнимателен.
     
  11. Scr1pt_

    Scr1pt_ New Member

    Публикаций:
    0
    Регистрация:
    14 мар 2007
    Сообщения:
    34
    А точнее бит D в дескрипторе сегмента в защищённом режиме...

    В процессе...
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Это не верно. В P6 и атлонах код считывается из кэша 16-байтными выравненными ifetch-блоками и помещается в 32-байтный буфер, который как раз и разруливает ситуации разбивки инструкций границами 16-байтных блоков. Отсюда и вытекают рекомендации выравнивания меток перехода на 16, т.к. в этом случае ifetch-блок будет содержать макс.число полезных инструкций и пока они обрабатываются декодером, безболезненно подгружается следующий блок. А если метка перехода расположена близко к концу ifetch-блока, то полезных полных инструкций для 3-канального декодера в таком блоке может быть мало (2, 1 или 0 если первая же инструкция разбивается границей блока), поэтому декодер на таком блоке работает не на максимуме или даже вхолостую. Аналогично и с длиной команд - для эффективной работы декодера в 16-байтном блоке должно содержаться не менее 3-х простых (direct path) инструкций
     
  13. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    А вот к примеру дизассемблер от Микрософта вот таким образом реагирует на повторение префиксов

    Код (Text):
    1. 1040B210 DISX86@Vmt18    proc near
    2. 1040B210                 mov     eax, dword ptr [esp+Address+4]
    3. 1040B214                 sub     esp, 0Ch
    4. 1040B217                 xor     edx, edx
    5. 1040B219                 push    ebx
    6. 1040B21A                 push    ebp
    7. 1040B21B                 mov     ebp, ecx
    8. 1040B21D                 push    esi
    9. 1040B21E                 mov     ecx, dword ptr [esp+18h+Address]
    10. 1040B222                 cmp     eax, edx
    11. 1040B224                 mov     [ebp+28h], ecx
    12. 1040B227                 push    edi
    13. 1040B228                 mov     [ebp+2Ch], eax
    14. 1040B22B                 ja      loc_1040B30F
    15. 1040B231                 cmp     ecx, 0FFFFFFFFh
    16. 1040B234                 ja      loc_1040B30F
    17. 1040B23A                 mov     ecx, [ebp+8]
    18. 1040B23D                 mov     eax, [esp+1Ch+From]
    19. 1040B241                 mov     esi, [esp+1Ch+MaxBytes]
    20. 1040B245                 cmp     ecx, edx
    21. 1040B247                 mov     [ebp+30h], eax
    22. 1040B24A                 mov     [ebp+34h], esi
    23. 1040B24D                 setnz   al
    24. 1040B250                 cmp     esi, edx
    25. 1040B252                 mov     [ebp+38h], edx
    26. 1040B255                 mov     [ebp+50h], al   ; fAddressSize
    27. 1040B258                 mov     [ebp+51h], al   ; fOperandSize
    28. 1040B25B                 mov     [ebp+52h], dl   ; fSegPrefix
    29. 1040B25E                 mov     [ebp+53h], dl   ; fRepPrefix
    30. 1040B261                 mov     [ebp+55h], dl   ; fOperandSizePrefix
    31. 1040B264                 mov     [ebp+54h], dl   ; fAddressSizePrefix
    32. 1040B267                 mov     [ebp+58h], edx  ; fCopPos
    33. 1040B26A                 jz      loc_1040B30F
    34. 1040B270 loc_1040B270:                           ; fSrcPtr
    35. 1040B270                 mov     eax, [ebp+30h]
    36. 1040B273                 mov     edi, [ebp+38h]  ; fBytes
    37. 1040B276                 inc     edi
    38. 1040B277                 mov     bl, [eax]
    39. 1040B279                 lea     edx, [eax+1]
    40. 1040B27C                 mov     byte ptr [esp+1Ch+b], bl
    41. 1040B280                 mov     [ebp+30h], edx
    42. 1040B283                 mov     eax, [esp+1Ch+b]
    43. 1040B287                 mov     [ebp+38h], edi
    44. 1040B28A                 and     eax, 0FFh       ; opcode
    45. 1040B28F                 lea     ecx, [eax+eax*2]
    46. 1040B292                 lea     ecx, OpInfos.name[ecx*4]
    47. 1040B299                 mov     [ebp+4Ch], ecx  ; fOpInfo
    48. 1040B29C                 cmp     dword ptr [ecx], 0
    49. 1040B29F                 jnz     loc_1040B348
    50. 1040B2A5                 add     eax, -0Fh
    51. 1040B2A8                 cmp     eax, 0E4h
    52. 1040B2AD                 ja      short loc_1040B30F
    53. 1040B2AF                 xor     ecx, ecx
    54. 1040B2B1                 mov     cl, ds:byte_1040B8C8[eax]
    55. 1040B2B7                 jmp     ds:off_1040B8B0[ecx*4]
    56. 1040B2BE locSegmentPrefix:
    57. 1040B2BE                 mov     al, [ebp+52h]
    58. 1040B2C1                 test    al, al
    59. 1040B2C3                 jnz     short loc_1040B30F
    60. 1040B2C5                 mov     [ebp+52h], bl   ; fSegPrefix
    61. 1040B2C8                 jmp     short loc_1040B304
    62. 1040B2CA locOperandSizePrefix:
    63. 1040B2CA                 mov     al, [ebp+55h]
    64. 1040B2CD                 test    al, al
    65. 1040B2CF                 jnz     short loc_1040B30F
    66. 1040B2D1                 mov     al, [ebp+51h]   ; fOperandSize
    67. 1040B2D4                 mov     byte ptr [ebp+55h], 1 ; fOperandSizePrefix
    68. 1040B2D8                 test    al, al
    69. 1040B2DA                 setz    dl
    70. 1040B2DD                 mov     [ebp+51h], dl
    71. 1040B2E0                 jmp     short loc_1040B304
    72. 1040B2E2 locAddressSizePrefix:
    73. 1040B2E2                 mov     al, [ebp+54h]
    74. 1040B2E5                 test    al, al
    75. 1040B2E7                 jnz     short loc_1040B30F
    76. 1040B2E9                 mov     al, [ebp+50h]   ; fAddressSize
    77. 1040B2EC                 mov     byte ptr [ebp+54h], 1 ; fAddressSizePrefix
    78. 1040B2F0                 test    al, al
    79. 1040B2F2                 setz    al
    80. 1040B2F5                 mov     [ebp+50h], al
    81. 1040B2F8                 jmp     short loc_1040B304
    82. 1040B2FA locRepPrefix:
    83. 1040B2FA                 mov     al, [ebp+53h]
    84. 1040B2FD                 test    al, al
    85. 1040B2FF                 jnz     short loc_1040B30F
    86. 1040B301                 mov     [ebp+53h], bl   ; fRepPrefix
    87. 1040B304 loc_1040B304:
    88. 1040B304                 cmp     edi, esi
    89. 1040B306                 mov     [ebp+58h], edi  ; fCopStart
    90. 1040B309                 jnz     loc_1040B270
    91. 1040B30F loc_1040B30F:  ;return 0
    92. 1040B30F                 pop     edi
    93. 1040B310                 pop     esi
    94. 1040B311                 pop     ebp
    95. 1040B312                 xor     eax, eax
    96. 1040B314                 pop     ebx
    97. 1040B315                 add     esp, 0Ch
    98. 1040B318                 retn    10h
    Если префикс уже встретился, возвращается 0, а в случае валидной инструкции возвращается ее длина.
    Видимо учитывается, что компилятор не создает "дикие" наборы префиксов, а вот человек может... :)
     
  14. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    crypto
    detours? оно вообще глючное.
     
  15. Scr1pt_

    Scr1pt_ New Member

    Публикаций:
    0
    Регистрация:
    14 мар 2007
    Сообщения:
    34
    Поле SIB очень даже может совмещаться с immediate offset!

    Например: если поле mod = 10, r/m = 100, sib = 00011101 (1D), то эффективный адрес операнда высчитывается как смещ_32[ebp][ebx]. Здесь главное, чтобы на месте базового регистра находился 101, именно он определяет появление 32-битного смещения.

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

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Scr1pt_
    мда) туплю
     
  17. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Scr1pt_
    Немного не так.
    Если поле base байта SIB равно 101b (EBP) и поле mod байта ModR/M равно 00b, то нет базового регистра, а в качестве базы используется смещение (DWORD).

    Наличие и размер смещения определяется только полем mod (за исключением этого случая, а также когда поле memr байта ModR/M равно 101b (EBP))
     
  18. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Не влияет никак. А сосуществует очень просто - ни его размер, ни вообще наличие (отсутствие) не определяется байтами modr/m и sib.

    Присутствует ли в инструкции непосредственный операнд, определяется по опкоду (по самой инструкции), а его размер зависит от режима (16/32) наличия/отсутствия префикса 66h и битов S и W в опкоде.

    Код (Text):
    1. /*
    2.  *  CalcImmSize - расчет длины непосредственного операнда
    3.  */
    4. byte CalcImmSize(bool OS, bool W, bool S)
    5. {
    6.     byte Length = 0;
    7.  
    8.     if (OS) Mode32 = !Mode32;
    9.  
    10.     if (S)
    11.     {
    12.         // Бит S инструкции установлен, длина - 1 байт
    13.         Length = 1;
    14.     }
    15.     else if (!W)
    16.     {
    17.         // Бит S не установлен и бит W не установлен, длина - 1 байт
    18.         Length = 1;
    19.     }
    20.     else if (Mode32)
    21.     {
    22.         // Бит S не установлен, бит W установлен и 32-х разрядный режим
    23.         // Длина - 4 байта
    24.         Length = 4;
    25.     }
    26.     else
    27.     {
    28.         // Бит S не установлен, бит W установлен и 16-ти разрядный режим
    29.         // Длина - 2 байта
    30.         Length = 2;
    31.     }
    32.  
    33.     if (OS) Mode32 = !Mode32;
    34.  
    35.     return Length;
    36. }
     
  19. Scr1pt_

    Scr1pt_ New Member

    Публикаций:
    0
    Регистрация:
    14 мар 2007
    Сообщения:
    34
    На мой взгляд в этом коде неправильно трактуется бит S:

    Получается, что если S = 1, то операнд 16-32 разрядный (смотря по размеру операндов), если S = 0 - операнд 8-разряден.

    Чем вообще отличаются биты W и S? Похоже, что по функциональному назначению лни одинаковы...

    И ещё: подскажите кто-нибудь чему равен индексный регистр, при коде этого самого регистра в поле sib, равному 100?
    У меня в учебнике стоит прочерк, комментариев нет, вот я и хочу понять, что бы это значило.
     
  20. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ничему.
    Например,
    004011C0 > 8B044E MOV EAX, DWORD PTR [ESI+ECX*2]
    а если поставить, например, 66 (у него Index=100):
    004011C0 > 8B0466 MOV EAX, DWORD PTR [ESI]
    То есть он не используется.