Спасибо, но нужно с одновременным занулением старшего байта: там тоже может содержаться ненужная инфа. Я так понимаю что аналога movzx не будет и одной командой не обойтись?
1. В 32х битном регистре 4 байта. 2. В моем примере зануляется старшая часть регистра (СТАРШИЕ 2 байта) 3. Одной командой не обойтись
Ящетаю, ТСу поможет вот это: Код (Text): SHLD EBX, EAX, 10h; MOVZX EBX, BL; [UPD:] на всякий случай перепроверил — да, SHLD не изменяет второй операнд.
О, большое спасибо! Это именно то что нужно! Видимо нужен справочник команд поновее, shld в моем нету.
А может вы заодно подскажете как можно оптимизировать такую простыню? Код (Text): CMP dl,%INTEGER.1 JE near .INT1 CMP dl,%INTEGER.2 JE near .INT2 CMP dl,%INTEGER.4 JE near .INT4 CMP dl,%UINTEGER.1 JE near .UINT1 CMP dl,%UINTEGER.2 JE near .UINT2 CMP dl,%UINTEGER.4 JE near .UINT4 CMP dl,%STRING JE near .STRING CMP dl,0 JE near .CRLF CMP dl,%CONST.REG JE near .REG CMP dl,%CONST.UREG JE near .UREG CMP dl,%CONST.STRING JE near .STRING CMP dl,%CONST.INTEGER JE near .SYMBOL CMP dl,%CONST.FLAGS JE near .FLAGS Участок кода разбирает параметры переданные ему и формирует из них строку, но так как каждый тип требует отдельной подпрограммы перевода то получается вот такая фигня "смерть конвейеру"...
xRom2 Самый короткий вариант - не всегда самый быстрый. Shld - это сложная (complex) инструкция, состоящая из нескольких микроопераций, которая и декодируется дольше и исполняется тоже. Поэтому вариант из трех простых операций может работать быстрее Если все сравнения производятся с константами, то нужно вместо кучи if использовать оптимизацию switch\case. Если константы идут по порядку, то ва-аще элементарно - один переход через массив указателей. Если не по порядку, то нужно кумекать как сгруппировать их в диапазоны для сокращения кол-ва проверок. Проще всего реализовать это дело на С\С++ с хорошим оптимизатором и посмотреть, что из этого получается на асме
Спасибо, учту. Ну константыто я задаю, переделал чтобы шли по порядку и вся та простыня, превратилась в такой код: Вот код обработки: Код (Text): LEA ebp,[esp+32+4] MOV ecx,[ebp] ;количество параметров MOV edi,!tmp+4 ;буфер для вывода @@: MOV edx,[ebp+ecx*8-4] ;тип параметра, система счисления и число цифр для вывода если это число MOV eax,[ebp+ecx*8] ;адрес параметра или прямое значение если регистр MOVZX ebx,dl ;получаем тип параметра, одновременно индекс в таблице ссылок LEA ebx,[..table+ebx*8] ;JMP dword [ebx] CALL dword [ebx] CMP edi,!tmp+65535 JAE near .EXIT .LOOP: DEC ecx JNZ @b JMP near .EXIT А вот такое количество параметров надо было бы сверять. Таблица однозначно рулит. Кстати вот и она (там где метка .LOOP - это заглушка, то есть обработчик типа просто еще не написан). Кстати как быстрее уходить на обработку и возвращаться в цикл: двумя jmp или call/ret? Код (Text): ..table: dd !print.CRLF ,!fprint.CRLF dd !print.STRING,!fprint.STRING ;%STRING dd !print.LOOP ,!fprint.LOOP ;%WSTRING dd !print.LOOP ,!fprint.LOOP ;%ZSTRING dd !print.INT1 ,!fprint.INT1 ;%INTEGER.1 dd !print.INT2 ,!fprint.INT2 ;%INTEGER.2 dd !print.INT4 ,!fprint.INT4 ;%INTEGER.4 dd !print.LOOP ,!fprint.LOOP ;%INTEGER.8 dd !print.UINT1 ,!fprint.UINT1 ;%UINTEGER.1 dd !print.UINT2 ,!fprint.UINT2 ;%UINTEGER.2 dd !print.UINT4 ,!fprint.UINT4 ;%UINTEGER.4 dd !print.LOOP ,!fprint.LOOP ;%UINTEGER.8 dd !print.LOOP ,!fprint.LOOP ;%FLOAT.4 dd !print.LOOP ,!fprint.LOOP ;%FLOAT.8 dd !print.LOOP ,!fprint.LOOP ;%FLOAT.10 dd !print.LOOP ,!fprint.LOOP ;%D.STRING dd !print.LOOP ,!fprint.LOOP ;%D.WSTRING dd !print.LOOP ,!fprint.LOOP ;%D.ZSTRING dd !print.LOOP ,!fprint.LOOP ;%D.INTEGER.1 dd !print.LOOP ,!fprint.LOOP ;%D.INTEGER.2 dd !print.LOOP ,!fprint.LOOP ;%D.INTEGER.4 dd !print.LOOP ,!fprint.LOOP ;%D.INTEGER.8 dd !print.LOOP ,!fprint.LOOP ;%D.UINTEGER.1 dd !print.LOOP ,!fprint.LOOP ;%D.UINTEGER.2 dd !print.LOOP ,!fprint.LOOP ;%D.UINTEGER.4 dd !print.LOOP ,!fprint.LOOP ;%D.UINTEGER.8 dd !print.LOOP ,!fprint.LOOP ;%D.FLOAT.4 dd !print.LOOP ,!fprint.LOOP ;%D.FLOAT.8 dd !print.LOOP ,!fprint.LOOP ;%D.FLOAT.10 dd !print.REG ,!fprint.REG ;%CONST.REG dd !print.UREG ,!fprint.UREG ;%CONST.UREG dd !print.SYMBOL,!fprint.SYMBOL ;%CONST.INTEGER dd !print.LOOP ,!fprint.LOOP ;%CONST.FLOAT dd !print.STRING,!fprint.STRING ;%CONST.STRING dd !print.LOOP ,!fprint.LOOP ;%CONST.ST dd !print.FLAGS ,!fprint.FLAGS ;%CONST.FLAGS dd !print.LOOP ,!fprint.LOOP ;%CONST.ADDRESS
Сам понимаешь, что call\ret это те же jmp, но с доп.push\pop, соотв-но это те же complex-инструкции, которые нагружают конвеер доп.микроопами. Хотя при таком изобилии возможных условных переходов, разницы скорее всего и не заметишь, т.к. она утонет на фоне штрафов за их неверное предсказание