Как быстрее всего сделать вот так:

Тема в разделе "WASM.BEGINNERS", создана пользователем xRom2, 21 ноя 2011.

  1. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    Расширить нулями третий байт любого 32битного регистра на весь ДРУГОЙ 32битный регистр?
    [​IMG]
     
  2. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    mov ebx, eax
    shr ebx, 16
     
  3. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    Спасибо, но нужно с одновременным занулением старшего байта: там тоже может содержаться ненужная инфа. Я так понимаю что аналога movzx не будет и одной командой не обойтись?
     
  4. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    1. В 32х битном регистре 4 байта.
    2. В моем примере зануляется старшая часть регистра (СТАРШИЕ 2 байта)
    3. Одной командой не обойтись
     
  5. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Ящетаю, ТСу поможет вот это:
    Код (Text):
    1. SHLD EBX, EAX, 10h;
    2. MOVZX EBX, BL;
    [UPD:] на всякий случай перепроверил — да, SHLD не изменяет второй операнд.
     
  6. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    О, большое спасибо! Это именно то что нужно! Видимо нужен справочник команд поновее, shld в моем нету.
     
  7. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    А может вы заодно подскажете как можно оптимизировать такую простыню?
    Код (Text):
    1.  
    2.          CMP       dl,%INTEGER.1
    3.           JE        near .INT1
    4.           CMP       dl,%INTEGER.2
    5.           JE        near .INT2
    6.           CMP       dl,%INTEGER.4
    7.           JE        near .INT4
    8.           CMP       dl,%UINTEGER.1
    9.           JE        near .UINT1
    10.           CMP       dl,%UINTEGER.2
    11.           JE        near .UINT2
    12.           CMP       dl,%UINTEGER.4
    13.           JE        near .UINT4
    14.           CMP       dl,%STRING
    15.           JE        near .STRING
    16.          
    17.           CMP       dl,0
    18.           JE        near .CRLF
    19.           CMP       dl,%CONST.REG
    20.           JE        near .REG
    21.           CMP       dl,%CONST.UREG
    22.           JE        near .UREG
    23.           CMP       dl,%CONST.STRING
    24.           JE        near .STRING
    25.           CMP       dl,%CONST.INTEGER
    26.           JE        near .SYMBOL
    27.           CMP       dl,%CONST.FLAGS
    28.           JE        near .FLAGS
    Участок кода разбирает параметры переданные ему и формирует из них строку, но так как каждый тип требует отдельной подпрограммы перевода то получается вот такая фигня "смерть конвейеру"...
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    xRom2
    Самый короткий вариант - не всегда самый быстрый. Shld - это сложная (complex) инструкция, состоящая из нескольких микроопераций, которая и декодируется дольше и исполняется тоже. Поэтому вариант из трех простых операций может работать быстрее

    Если все сравнения производятся с константами, то нужно вместо кучи if использовать оптимизацию switch\case. Если константы идут по порядку, то ва-аще элементарно - один переход через массив указателей. Если не по порядку, то нужно кумекать как сгруппировать их в диапазоны для сокращения кол-ва проверок. Проще всего реализовать это дело на С\С++ с хорошим оптимизатором и посмотреть, что из этого получается на асме
     
  9. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    Спасибо, учту.

    Ну константыто я задаю, переделал чтобы шли по порядку и вся та простыня, превратилась в такой код:
    Вот код обработки:
    Код (Text):
    1.           LEA       ebp,[esp+32+4]
    2.           MOV       ecx,[ebp]                  ;количество параметров
    3.           MOV       edi,!tmp+4                 ;буфер для вывода
    4. @@:       MOV       edx,[ebp+ecx*8-4]    ;тип параметра, система счисления и число цифр для вывода если это число
    5.           MOV       eax,[ebp+ecx*8]        ;адрес параметра или прямое значение если регистр
    6.           MOVZX     ebx,dl                     ;получаем тип параметра, одновременно индекс в таблице ссылок
    7.           LEA       ebx,[..table+ebx*8]
    8.           ;JMP       dword [ebx]
    9.           CALL      dword [ebx]
    10.           CMP       edi,!tmp+65535
    11.           JAE       near .EXIT
    12. .LOOP:    DEC       ecx
    13.           JNZ       @b
    14.           JMP       near .EXIT
    А вот такое количество параметров надо было бы сверять. Таблица однозначно рулит. Кстати вот и она (там где метка .LOOP - это заглушка, то есть обработчик типа просто еще не написан). Кстати как быстрее уходить на обработку и возвращаться в цикл: двумя jmp или call/ret?
    Код (Text):
    1. ..table:  dd        !print.CRLF  ,!fprint.CRLF      
    2.           dd        !print.STRING,!fprint.STRING    ;%STRING            
    3.           dd        !print.LOOP  ,!fprint.LOOP      ;%WSTRING            
    4.           dd        !print.LOOP  ,!fprint.LOOP      ;%ZSTRING            
    5.                                                                        
    6.           dd        !print.INT1  ,!fprint.INT1      ;%INTEGER.1          
    7.           dd        !print.INT2  ,!fprint.INT2      ;%INTEGER.2          
    8.           dd        !print.INT4  ,!fprint.INT4      ;%INTEGER.4          
    9.           dd        !print.LOOP  ,!fprint.LOOP      ;%INTEGER.8          
    10.                                                                        
    11.           dd        !print.UINT1 ,!fprint.UINT1     ;%UINTEGER.1        
    12.           dd        !print.UINT2 ,!fprint.UINT2     ;%UINTEGER.2        
    13.           dd        !print.UINT4 ,!fprint.UINT4     ;%UINTEGER.4        
    14.           dd        !print.LOOP  ,!fprint.LOOP      ;%UINTEGER.8        
    15.                                                                        
    16.           dd        !print.LOOP  ,!fprint.LOOP      ;%FLOAT.4            
    17.           dd        !print.LOOP  ,!fprint.LOOP      ;%FLOAT.8            
    18.           dd        !print.LOOP  ,!fprint.LOOP      ;%FLOAT.10          
    19.                                                                        
    20.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.STRING          
    21.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.WSTRING          
    22.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.ZSTRING          
    23.                                                                        
    24.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.INTEGER.1        
    25.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.INTEGER.2        
    26.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.INTEGER.4        
    27.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.INTEGER.8        
    28.                                                                        
    29.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.UINTEGER.1      
    30.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.UINTEGER.2      
    31.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.UINTEGER.4      
    32.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.UINTEGER.8      
    33.                                                                        
    34.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.FLOAT.4          
    35.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.FLOAT.8          
    36.           dd        !print.LOOP  ,!fprint.LOOP      ;%D.FLOAT.10        
    37.                                                                        
    38.           dd        !print.REG   ,!fprint.REG       ;%CONST.REG          
    39.           dd        !print.UREG  ,!fprint.UREG      ;%CONST.UREG        
    40.                                                                        
    41.           dd        !print.SYMBOL,!fprint.SYMBOL    ;%CONST.INTEGER      
    42.           dd        !print.LOOP  ,!fprint.LOOP      ;%CONST.FLOAT        
    43.           dd        !print.STRING,!fprint.STRING    ;%CONST.STRING      
    44.           dd        !print.LOOP  ,!fprint.LOOP      ;%CONST.ST          
    45.           dd        !print.FLAGS ,!fprint.FLAGS     ;%CONST.FLAGS        
    46.           dd        !print.LOOP  ,!fprint.LOOP      ;%CONST.ADDRESS
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Сам понимаешь, что call\ret это те же jmp, но с доп.push\pop, соотв-но это те же complex-инструкции, которые нагружают конвеер доп.микроопами. Хотя при таком изобилии возможных условных переходов, разницы скорее всего и не заметишь, т.к. она утонет на фоне штрафов за их неверное предсказание