Code (Text): 004014A0 > BD 01000000 MOV EBP,1 004014A5 . 807C3D 00 00 CMP BYTE PTR SS:[EBP+EDI],0 004014A0 > B9 01000000 MOV ECX,1 004014A5 . 803C39 00 CMP BYTE PTR DS:[ECX+EDI],0 Почему Olly выдаёт для ebp SS, а для ecx - DS ? ebp ничего кроме стека адресовать не должен? Этим объясняется разная длина CMP BYTE PTR SS:[EBP+EDI],0 и CMP BYTE PTR DS:[ECX+EDI],0 ? (Исходя из того, что данные на стеке должны быть кратными ворду) И как быть с тем, что байт, адресуемый инструкцией, находится не в стеке?
Фасм так скомпилил Code (Text): 00401000 $ BD 01000000 MOV EBP,1 00401005 . 803C2F 01 CMP BYTE PTR DS:[EDI+EBP],1 00401009 . B9 01000000 MOV ECX,1 0040100E . 803C0F 01 CMP BYTE PTR DS:[EDI+ECX],1
Если EBP используется в качестве базового регистра, то обращения по умолчанию производятся к сегменту стека, указываемому в SS. Под виндой это пофиг, ибо flat, а вот под, например, DOS-extender'ом это надо не забывать. Без EBP на байт короче, т.к. к [bp/ebp] можно обратиться только как [...bp/ebp+0]. Объяснение этому -- структура байтов mod_reg_r/m и SIB в IA32.
Попробовал явно указать cmp byte ptr ds:[edi+ebp],0 Получил те же 2 байта для нуля, и опкод с приставкой 3E:. Code (Text): 004014A0 > BD 01000000 MOV EBP,1 004014A5 . 3E:807C3D 00 00 CMP BYTE PTR DS:[EBP+EDI],0 ? В принципе 1 байт ничего не значит, просто неясно, почему. ebp должен адресовать кратное ворду?
Преффиксов переопределения сегмента тут вооюще нет, так что правильным будет вариант 807C3D0000 - cmp byte ptr [ebp+edi], 00h 803C3900 - cmp byte ptr [ecx+edi], 00h
Получается, фасм допускает более вольное обращение с кодами? А масм с этим строже. ModRegR/m - это что за фигня такая?
Да, адресации с ebp самим по себе нет, только с 8 или 32 битным смещением - такой формат. Сами по себе могут быть адресованы любые стандартные регистры кроме ebp и esp, esp вообще можно но только с байтом sib при этом размер инструкции такой же как и c ebp.
Code (Text): 004014A5 . 807C3D 00 00 CMP BYTE PTR SS:[EBP+EDI],0 это известный баг masm. решение где-то приводил The Svin что-то вроде (не проверял) CMP BYTE PTR [1*EBP+EDI],0
баг должен приводить к сбою. Но код не сбоит. Примерно с таким же основанием можно сказать, что это баг fasm - отсутствие нуля, если регистр должен быть со смещением, а фасм его не ставит
Насколько я понял, имеется в виду баг, попусту удлинняющий команду, но не изменяющий ее смысла, поэтому баг не приводит к сбою. Если компилятор подставляет лишний префикс там, где это не нужно, то это и есть баг компилятора.
Хорошим тоном для компиляторов ассемблера считается генерировать минимальный по размеру опкод, если обратное не форсировано модификаторами. Считать такое поведение masm багом или нет - личное дело каждого. IMHO плюсов masm это не прибавляет
Как впрочем и фасму тоже это ничего не прибавляет. Малый размер - это для глистописателей Меня это не привлекает. А хороший тон - это отсутствие тона, я сам выберу тон, который нужен. Любителям хорошего тона можно посоветовать C++, delphi, visualbasic - там всё зафиксировано, запротоколировано и засунуто в рамки тона. Асм мне нужен для того, чтобы действовать по принципу "что хочу, то и ворочу".
Он не будет сбоить если DS=SS там без разницы что базовый что индексный. Если о кодировании в Win32 то и в режиме супервизора и в пользовательском базы в дескрипторах у SS\DS равны 0. Но в режиме пользовательском у них вообще одни селекторы а в режиме ядра селекторы разные (это объясняется архитектурой не Win32 а I-32, у супервизора дескриптор стека не может иметь привилегии пользователя, у него там должен быть 0) Там когда разбирались в основном внимание было не на сбои кода а на размер инструкций,- у них получались разные размеры из-за специфики кодирования ebp как составляющей адреса. ebp в качестве базы будет обязательно с дисплейсментом, что раздражает когда можно обойтись без него в случаях index+base.
cresta А ты че кипятишься то ESP и EBP - "обиженные" регистры и обижены они не от хорошей жизни, а от нехватки битов кодировки ModR/M. Я вот только не пойму - ты пробовал вместо [ebp+edi] записать [edi+ebp] или тебе непременно хочется чтобы ebp был базой ?
Хм, не знаю как можно с этого делать проблему для обсуждения. Вполне логично, что ассемблер первый указанный регистр считает базой, если не указан множитель. А ebp не может быть чистой базой, без смещения. На этом строятся такие команды как mov xxx, [reg*index+offset], т.е. SIB без базы. Вот, например, команда mov dword ptr [ebp+edi], 0 скомпиленная тасмом: Code (Text): C7443D0000000000 mov d,[ebp][edi][00000], 00 а вот та же команда, но mov dword ptr [edi+ebp], 0 результат Code (Text): C7042F00000000 mov d,[edi][ebp], 00 Т.е. переставить регистры => -1 байт.
Угу, это проблема Масма, там как не переставляй он ebp считает базой если множитель принудительно не поставить.
cresta > Для такого подхода некоторые опкоды в masm придётся кодировать через DB The Svin > И может привести к ошибкам, когда в алгоритмах каким-то образом используется размер опкода.
leo Да не кипячусь я, просто S_T_A_S_ постоянно шпыняет масм, а мне не нравится это И мне тоже хочется пнуть фасм. Собственно проблемы тут никакой нет, воткнуть db...и всё, если так уж необходимо урвать один байт. Просто заметил такой эффект и решил спросить, в чём дело. Для обчего развития